[PATCH] handsfree profile plugins and driver framework
by Zhang, Zhenhua
Hi,
Attached patch is the Bluetooth handsfree profile (HFP) support for oFono. It
includes hfp plugin and the basic driver backend framework. The plugin use
'AT+BRSF=118' to inform AG supported features and perform serivce level
connection in modem's power on stage. The voicecall driver for HFP is planed
to add later. Handsfree profile actually need BlueZ support for SCO connection
for routing audio which is not in this patch.
You may need to create /dev/rfcomm0 through 'rfcomm bind <port> <bdaddr>
<channel>' and then specify device in modem.conf. For example,
rfcomm bind 0 00:22:A9:8C:AF:34 2
The channel number of HFP audio gateway could be found though 'sdptool browse'
result.
Regards,
Zhenhua
12 years, 7 months
[PATCH] Parse +CUSD responses.
by Andrzej Zaborowski
Register for "+CUSD:" unsolicited responses, also parse +CUSD
lines appearing as part of response to AT+CUSD (this form is still
used on Nokia phones that emulate AT when connected to a PC, and
both forms are allowed by the spec). The latter form is treated
differently to make sure the Initiate callback happens before
ofono_ussd_notify is called.
USSD.Initiate still returns a string, this may be wrong because
when the network returns data coded in 8-bits we have no information
on the character set used, everything is "user-specified" for the
8-bit coding in the 23.038 and technically we should return an array
of bytes. I only handle 7-bit and 8-bit responses, other codings
are not specified and I didn't manage to make the network send me
anything other than 7-bit coded string, although I managed to send a
UCS2-coded USSD string -- the network still only responded with DCS
= 15 (but the response content didn't make any sense). The responses
from my network were always in the local language but with non-ASCII
characters stripped, regardless of the language set in the DCS by me.
I removed the "TODO: be able to send UCS2 string" because the string
we send is first checked to be a valid USSD string so we already know
it can be encoded with GSM 7-bits.
---
drivers/atmodem/ussd.c | 110 ++++++++++++++++++++++++++++++++++++++++++------
src/ussd.c | 3 +
2 files changed, 100 insertions(+), 13 deletions(-)
diff --git a/drivers/atmodem/ussd.c b/drivers/atmodem/ussd.c
index 1d819a3..e35cf72 100644
--- a/drivers/atmodem/ussd.c
+++ b/drivers/atmodem/ussd.c
@@ -40,39 +40,103 @@
#include "atmodem.h"
+struct cusd_req {
+ ofono_ussd_cb_t cb;
+ void *data;
+ struct ofono_ussd *ussd;
+};
+
+static const char *cusd_prefix[] = { "+CUSD:", NULL };
static const char *none_prefix[] = { NULL };
+static void cusd_parse(GAtResult *result, struct ofono_ussd *ussd)
+{
+ GAtResultIter iter;
+ int status;
+ int dcs;
+ const guint8 *content;
+ int length;
+ char *converted = NULL;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CUSD:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &status))
+ return;
+
+ if (!g_at_result_iter_next_hexstring(&iter, &content, &length))
+ goto out;
+
+ if (!g_at_result_iter_next_number(&iter, &dcs))
+ goto out;
+
+ /* All 7-bit coding schemes - there's no need to distinguish
+ * between the different schemes because the modem is tasked
+ * with presenting us with only raw 7-bit characters.
+ */
+ if ((dcs & 0xf0) == 0x00 || dcs == 0x10 || (dcs & 0xf0) == 0x20 ||
+ (dcs & 0xf0) == 0x30 || (dcs & 0xcc) == 0x40 ||
+ (dcs & 0xfc) == 0x90 || (dcs & 0xf4) == 0xf0)
+ converted = convert_gsm_to_utf8(content, length,
+ NULL, NULL, 0);
+
+ /* All 8-bit coding schemes - again we can treat all of them
+ * the same, however we have no information about the character
+ * set used, for the moment return raw (upper layer will assume
+ * what we sent it is UTF-8 which may be wrong).
+ */
+ else if ((dcs & 0xcc) == 0x44 || (dcs & 0xfc) == 0x94 ||
+ (dcs & 0xf4) == 0xf4)
+ converted = g_strndup((char *) content, length);
+
+ /* No other encoding is mentioned in TS27007 7.15 */
+ else
+ ofono_error("Unsupported USSD data coding scheme (%02x)", dcs);
+
+out:
+ ofono_ussd_notify(ussd, status, converted);
+
+ if (converted)
+ g_free(converted);
+}
+
static void cusd_request_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
- struct cb_data *cbd = user_data;
- ofono_ussd_cb_t cb = cbd->cb;
+ struct cusd_req *cbd = user_data;
struct ofono_error error;
dump_response("cusd_request_cb", ok, result);
decode_at_error(&error, g_at_result_final_response(result));
- cb(&error, cbd->data);
+ cbd->cb(&error, cbd->data);
+
+ cusd_parse(result, cbd->ussd);
}
static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
ofono_ussd_cb_t cb, void *data)
{
GAtChat *chat = ofono_ussd_get_data(ussd);
- struct cb_data *cbd = cb_data_new(cb, data);
+ struct cusd_req *cbd = g_try_new0(struct cusd_req, 1);
unsigned char *converted = NULL;
int dcs;
int max_len;
+ int i;
+ int len;
long written;
char buf[256];
if (!cbd)
goto error;
+ cbd->cb = cb;
+ cbd->data = data;
+ cbd->ussd = ussd;
+
converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0);
- /* TODO: Be able to convert to UCS2, although the standard does not
- * indicate that this is actually possible
- */
if (!converted)
goto error;
else {
@@ -83,12 +147,15 @@ static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
if (written > max_len)
goto error;
- sprintf(buf, "AT+CUSD=1,\"%*s\",%d", (int) written, converted, dcs);
+ len = sprintf(buf, "AT+CUSD=1,\"");
+ for (i = 0; i < written; i ++)
+ len += sprintf(buf + len, "%02hhx", converted[i]);
+ sprintf(buf + len, "\",%d", dcs);
g_free(converted);
converted = NULL;
- if (g_at_chat_send(chat, buf, none_prefix,
+ if (g_at_chat_send(chat, buf, cusd_prefix,
cusd_request_cb, cbd, g_free) > 0)
return;
@@ -133,13 +200,28 @@ error:
CALLBACK_WITH_FAILURE(cb, data);
}
-static gboolean at_ussd_register(gpointer user)
+static void cusd_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_ussd *ussd = user_data;
+
+ dump_response("cssu_notify", TRUE, result);
+
+ cusd_parse(result, ussd);
+}
+
+static void at_ussd_register(gboolean ok, GAtResult *result, gpointer user)
{
struct ofono_ussd *ussd = user;
+ GAtChat *chat = ofono_ussd_get_data(ussd);
- ofono_ussd_register(ussd);
+ if (!ok) {
+ ofono_error("Could not enable CUSD notifications");
+ return;
+ }
+
+ g_at_chat_register(chat, "+CUSD:", cusd_notify, FALSE, ussd, NULL);
- return FALSE;
+ ofono_ussd_register(ussd);
}
static int at_ussd_probe(struct ofono_ussd *ussd, unsigned int vendor,
@@ -148,7 +230,9 @@ static int at_ussd_probe(struct ofono_ussd *ussd, unsigned int vendor,
GAtChat *chat = data;
ofono_ussd_set_data(ussd, chat);
- g_idle_add(at_ussd_register, ussd);
+
+ g_at_chat_send(chat, "AT+CSCS=\"HEX\"", NULL, NULL, NULL, NULL);
+ g_at_chat_send(chat, "AT+CUSD=1", NULL, at_ussd_register, ussd, NULL);
return 0;
}
diff --git a/src/ussd.c b/src/ussd.c
index be50296..2bf378d 100644
--- a/src/ussd.c
+++ b/src/ussd.c
@@ -313,6 +313,9 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
reply = dbus_message_new_method_return(ussd->pending);
+ if (!str)
+ str = "";
+
dbus_message_iter_init_append(reply, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
--
1.6.1
12 years, 7 months
[PATCH] API documentation fixes
by Marko Saukko
Hi,
Fixes for API documentation.
Regards,
Marko
---
doc/call-settings-api.txt | 4 ++--
doc/sim-api.txt | 10 +++++-----
doc/voicecall-api.txt | 2 +-
doc/voicecallmanager-api.txt | 2 +-
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/doc/call-settings-api.txt b/doc/call-settings-api.txt
index 870c748..5e5eb40 100644
--- a/doc/call-settings-api.txt
+++ b/doc/call-settings-api.txt
@@ -1,7 +1,7 @@
-Call Forwarding hierarchy
+Call Settings hierarchy
===============
Service org.ofono
-Interface org.ofono.CallForwarding
+Interface org.ofono.CallSettings
Object path [variable prefix]/{modem0,modem1,...}
Methods dict GetProperties()
diff --git a/doc/sim-api.txt b/doc/sim-api.txt
index 11ee4c8..9fe9a92 100644
--- a/doc/sim-api.txt
+++ b/doc/sim-api.txt
@@ -12,22 +12,22 @@ Methods dict GetProperties()
Possible Errors: [service].Error.InvalidArguments
- ChangePin(string type, string oldpin, string newpin)
+ void ChangePin(string type, string oldpin, string newpin)
Changes the pin given by string type.
- EnterPin(string type, string pin)
+ void EnterPin(string type, string pin)
Enters the currently pending pin. The type value must
match the pin type being asked in the PinRequired
property.
- ResetPin(string type, string puk, string newpin)
+ void ResetPin(string type, string puk, string newpin)
Provides the unblock key to the modem and if correct
resets the pin to the new value of newpin.
- LockPin(string type, string pin)
+ void LockPin(string type, string pin)
Activates the lock for the particular pin type. The
device will ask for a PIN automatically next time the
@@ -35,7 +35,7 @@ Methods dict GetProperties()
re-inserter. The current PIN is required for the
operation to succeed.
- UnlockPin(string type, string pin)
+ void UnlockPin(string type, string pin)
Deactivates the lock for the particular pin type. The
current PIN is required for the operation to succeed.
diff --git a/doc/voicecall-api.txt b/doc/voicecall-api.txt
index 62db5a1..b360cca 100644
--- a/doc/voicecall-api.txt
+++ b/doc/voicecall-api.txt
@@ -3,7 +3,7 @@ VoiceCall hierarchy
Service org.ofono
Interface org.ofono.VoiceCall
-Object path [variable prefix]/{modem0,modem1,...}/{call0,call1,...}
+Object path [variable prefix]/{modem0,modem1,...}/{voicecall01,voicecall02,...}
Methods dict GetProperties()
diff --git a/doc/voicecallmanager-api.txt b/doc/voicecallmanager-api.txt
index 361370a..7877ac5 100644
--- a/doc/voicecallmanager-api.txt
+++ b/doc/voicecallmanager-api.txt
@@ -70,7 +70,7 @@ Methods dict GetProperties()
Held calls is invalid, since in GSM a user can have
only a single Held call at a time.
- void HangupAllCalls()
+ void HangupAll()
Releases all calls.
--
1.6.0.4
12 years, 7 months
[PATCH] Free converted string after use.
by Andrzej Zaborowski
Also make sure we don't read beyond end of the string.
---
drivers/atmodem/ussd.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/atmodem/ussd.c b/drivers/atmodem/ussd.c
index c29f8f6..1d819a3 100644
--- a/drivers/atmodem/ussd.c
+++ b/drivers/atmodem/ussd.c
@@ -59,7 +59,7 @@ static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
{
GAtChat *chat = ofono_ussd_get_data(ussd);
struct cb_data *cbd = cb_data_new(cb, data);
- unsigned char *converted;
+ unsigned char *converted = NULL;
int dcs;
int max_len;
long written;
@@ -83,7 +83,10 @@ static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
if (written > max_len)
goto error;
- sprintf(buf, "AT+CUSD=1,\"%s\",%d", converted, dcs);
+ sprintf(buf, "AT+CUSD=1,\"%*s\",%d", (int) written, converted, dcs);
+
+ g_free(converted);
+ converted = NULL;
if (g_at_chat_send(chat, buf, none_prefix,
cusd_request_cb, cbd, g_free) > 0)
@@ -92,6 +95,8 @@ static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
error:
if (cbd)
g_free(cbd);
+ if (converted)
+ g_free(converted);
CALLBACK_WITH_FAILURE(cb, data);
}
--
1.6.1
12 years, 7 months
light test report for ofono v0.3
by Fu, Elva
Test Environment
-------------------------------
general PC (pre-installed FC11)
- ofono v0.3
- phonesim package
mobile phone (use it as modem)
-------------------------------
Test Scope
-------------------------------
- we mainly focus on checking basic functionality of ofono v0.3 (voice call, sms, phonebook etc.)
- voice call, multiparty call, phonebook, SIM and modem are tested in real network env. For others, we test them through simulator.
- bug verification: verify issues we found in v0.2
-------------------------------
Test Summary
-------------------------------
there are small changes between ofono v0.2 and v0.3. so good test result is expected. :-)
Total 63 test cases were executed during this round of testing.
Pass: 63
Fail: 0
issues we found in v0.2 were fixed already, many thanks!
-------------------------------
Details
-------------------------------
to make it readable, we summarized by feature list. :-)
features checkpoints test results comments
SMS Send/receive pass
Set service center address pass
More recipients pass
More segment pass
Voice call Dial pass
Accept pass
Reject pass
Hold pass
Receive pass
Release pass
Multiparty call Create pass
Hang up pass
Private chat pass
Hold pass
Sim Phonebook Read pass
SS CF pass
CB pass
CW pass
CLIR/CLIP pass
Setting AOC pass
CF/CB pass
GSM string pass
Modem pass
Networking pass
Sim Read IMSI pass
Read MSISDN pass
-------------------------------
Elva
12 years, 7 months
oFono gets multiplexer support
by Denis Kenzior
Hi All,
Just to let you know the initial support for multiplexing has been added to
oFono. The multiplexer infrastructure is fully customizable through the use
of drivers. Two drivers are currently supported, GSM 27.010 Basic and
Advanced modes.
The multiplexer is implemented in gatmux in the gatchat library. GAtMux
provides a simple interface, and returns a fully functional GIOChannel for
each multiplexer port. Thus it can easily be integrated with the existing
GAtChat functionality, or used to read / write raw information (e.g. ppp
frames)
This will allow oFono to implement everything in the main oFono process, and
not resort to a separate multiplexer daemon. The calypso modem plugin has
been updated to take advantage of 4 multiplexer channels.
Regards,
-Denis
12 years, 7 months
Re-add Manager.Create / Remove
by Andrzej Zaborowski
This is a small patch to revive Manager.Create and Manager.Remove that lets
you create a modem over D-Bus dynamically, for example in python that could
be:
modem_path = manager.Create('phonesim', { 'Port': 12345, 'Address':
'127.0.0.1' })
This is only posted for those who want to use the patch rather than for
merging.
---
src/manager.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 134 insertions(+), 0 deletions(-)
diff --git a/src/manager.c b/src/manager.c
index e35728a..9bf61ae 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -29,6 +29,8 @@
#include "ofono.h"
+static GSList *modems;
+
static DBusMessage *manager_get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -62,8 +64,140 @@ static DBusMessage *manager_get_properties(DBusConnection *conn,
return reply;
}
+static DBusMessage *manager_modem_create(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessageIter iter;
+ DBusMessageIter var;
+ DBusMessageIter var_iter;
+ DBusMessageIter var_value;
+ DBusMessage *reply;
+ char *type;
+ char *property;
+ dbus_bool_t bool_value;
+ dbus_int32_t int_value;
+ char *str_value;
+ const char *path;
+ struct ofono_modem *modem;
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return __ofono_error_invalid_args(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return __ofono_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&iter, &type);
+
+ modem = ofono_modem_create(type);
+ if (!modem)
+ return __ofono_error_failed(msg);
+
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&iter) !=
+ DBUS_TYPE_DICT_ENTRY)
+ goto error;
+
+ dbus_message_iter_recurse(&iter, &var);
+
+ while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
+ if (dbus_message_iter_get_arg_type(&var) !=
+ DBUS_TYPE_DICT_ENTRY)
+ goto error;
+
+ dbus_message_iter_recurse(&var, &var_iter);
+
+ if (dbus_message_iter_get_arg_type(&var_iter) !=
+ DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_get_basic(&var_iter, &property);
+
+ dbus_message_iter_next(&var_iter);
+
+ if (dbus_message_iter_get_arg_type(&var_iter) !=
+ DBUS_TYPE_VARIANT)
+ goto error;
+
+ dbus_message_iter_recurse(&var_iter, &var_value);
+
+ switch (dbus_message_iter_get_arg_type(&var_value)) {
+ case DBUS_TYPE_STRING:
+ dbus_message_iter_get_basic(&var_value, &str_value);
+
+ ofono_modem_set_string(modem, property, str_value);
+ break;
+
+ case DBUS_TYPE_INT32:
+ dbus_message_iter_get_basic(&var_value, &int_value);
+
+ ofono_modem_set_integer(modem, property, int_value);
+ break;
+
+ case DBUS_TYPE_BOOLEAN:
+ dbus_message_iter_get_basic(&var_value, &bool_value);
+
+ ofono_modem_set_boolean(modem, property, bool_value);
+ break;
+
+ default:
+ goto error;
+ }
+
+ dbus_message_iter_next(&var);
+ }
+
+ if (ofono_modem_register(modem) < 0) {
+ ofono_modem_remove(modem);
+
+ return __ofono_error_failed(msg);
+ }
+
+ modems = g_slist_prepend(modems, modem);
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ path = ofono_modem_get_path(modem);
+ dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
+error:
+ ofono_modem_remove(modem);
+
+ return __ofono_error_invalid_args(msg);
+}
+
+static DBusMessage *manager_modem_remove(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ char *path;
+ struct ofono_modem *modem;
+ GSList *l;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID))
+ return __ofono_error_invalid_args(msg);
+
+ for (l = modems; l; l = l->next) {
+ modem = l->data;
+
+ if (!strcmp(path, ofono_modem_get_path(modem))) {
+ ofono_modem_remove(modem);
+ return dbus_message_new_method_return(msg);
+ }
+ }
+
+ return __ofono_error_not_found(msg);
+}
+
static GDBusMethodTable manager_methods[] = {
{ "GetProperties", "", "a{sv}", manager_get_properties },
+ { "Create", "sa{sv}", "o", manager_modem_create },
+ { "Remove", "o", "", manager_modem_remove },
{ }
};
--
1.6.1
12 years, 7 months
[PATCH] support preferred network
by Gu, Yang
Hi,
This feature is to support operator preferred network and user preferred network. Operator preferred network is readonly, while user preferred network is readwrite. A corresponding test script is also added, and you can use it like: ./test-preferred-network 'UserPreferredNetworks' '10001' '10002' '10003'.
Regards,
-Yang
12 years, 7 months
Re: how ofono runs with simulator
by Jeroen Wouters
Gu, Yang wrote:
> The following steps work for latest 0.4 version:
>
> 1. Modify modem.conf to config your simulator
> # Sample for using phone simulator
> [phonesim]
> Driver=phonesim
> Address=127.0.0.1
> Port=12345
>
> 2. Start simulator by
> Phonesim -p 12345 -gui data/moblin.xml
>
> 3. Start ofono by
> ofonod -nd
>
> 4. power on the modem
> dbus-send --system --print-reply --dest=org.ofono /phonesim0 org.ofono.Modem.SetProperty string:Powered variant:boolean:true
Where can I find the moblin.xml file and the source code for the version of phonesim you used?
I've looked for the xml file, but I can't find it. I've also tried the steps you describe with Ofono 0.6 and the phonesim version I found here:
https://svn.openmoko.org/trunk/src/host/qemu-neo1973/phonesim/
and with a couple of other XML response files I found on the net, but whatever I do in the phonesim GUI, there is no response from Ofono.
Also, in Ofono, the /phonesim0 modem appears, but only has a org.ofono.SimManager interface, no VoiceCallManager.
Thanks,
Jeroen
12 years, 7 months
[PATCH] Autotool improvements.
by Pekka Pessi
From: Pekka Pessi <Pekka.Pessi(a)nokia.com>
Bootstrap script now tries to use explicitly versioned automake, which makes
life easier with scratchbox and friends. Bootstrap also uses autoreconf
instead of explictly running various autotools.
---
Makefile.am | 2 ++
bootstrap | 38 +++++++++++++++++++++++++++++++++-----
configure.ac | 3 ++-
3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index cf84bf7..9ade516 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,8 @@
AM_MAKEFLAGS = --no-print-directory
+ACLOCAL_AMFLAGS = -I m4
+
includedir = @includedir@/ofono
include_HEADERS = include/log.h include/plugin.h include/history.h \
diff --git a/bootstrap b/bootstrap
index 053f5c8..c751b3c 100755
--- a/bootstrap
+++ b/bootstrap
@@ -1,7 +1,35 @@
#!/bin/sh
-aclocal && \
- autoheader && \
- libtoolize --automake --copy --force &&
- automake --add-missing --copy && \
- autoconf
+if test -z "$AUTOMAKE"
+then
+ for version in 1.10 1.11 1.12
+ do
+ if which automake-$version > /dev/null
+ then
+ AUTOMAKE=automake-$version ACLOCAL=aclocal-$version
+ export AUTOMAKE ACLOCAL
+ break
+ fi
+ done
+fi
+
+if test -z "$AUTOMAKE"
+then
+ for version in 1.10 1.11 1.12
+ do
+ if automake --version | head -1 | fgrep -q $version
+ then
+ AUTOMAKE=automake ACLOCAL=aclocal
+ export AUTOMAKE ACLOCAL
+ fi
+ done
+fi
+
+# Remove libtool files (in case they conflict with older libtool)
+rm -f m4/libtool.m4 \
+ m4/lt~obsolete.m4 \
+ m4/ltoptions.m4 \
+ m4/ltsugar.m4 \
+ m4/ltversion.m4
+
+autoreconf --install --force "$@"
diff --git a/configure.ac b/configure.ac
index 4cc4449..55fd281 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,8 +1,9 @@
AC_PREREQ(2.60)
AC_INIT(ofono, 0.7)
-AM_INIT_AUTOMAKE([foreign subdir-objects])
+AM_INIT_AUTOMAKE([foreign subdir-objects 1.10])
AM_CONFIG_HEADER(config.h)
+AC_CONFIG_MACRO_DIR([m4])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
--
1.6.0.4
12 years, 7 months