* [PATCH 0/4] Add Suspended property to GPRS (take 3)
@ 2010-09-10 13:50 Mika Liljeberg
2010-09-10 13:50 ` [PATCH 1/4] TODO: Claim ownership of Suspended property for GPRS Mika Liljeberg
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Mika Liljeberg @ 2010-09-10 13:50 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 831 bytes --]
Comments from Denis applied.
Br,
MikaL
[PATCH 1/4] TODO: Claim ownership of Suspended property for GPRS
[PATCH 2/4] gprs: add Suspended property
[PATCH 3/4] isimodem: implement Suspended property
[PATCH 4/4] test: add enable-gprs and disable-gprs scripts
TODO | 3 +-
doc/connman-api.txt | 19 ++++++++++++
drivers/isimodem/debug.c | 25 ++++++++++++++++
drivers/isimodem/debug.h | 2 +
drivers/isimodem/gpds.h | 17 +++++++++++
drivers/isimodem/gprs.c | 56 +++++++++++++++++++++++++++++++++++-
include/gprs.h | 10 ++++++
src/gprs.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
test/disable-gprs | 20 +++++++++++++
test/enable-gprs | 20 +++++++++++++
10 files changed, 242 insertions(+), 2 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] TODO: Claim ownership of Suspended property for GPRS
2010-09-10 13:50 [PATCH 0/4] Add Suspended property to GPRS (take 3) Mika Liljeberg
@ 2010-09-10 13:50 ` Mika Liljeberg
2010-09-10 13:50 ` [PATCH 2/4] gprs: add Suspended property Mika Liljeberg
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Mika Liljeberg @ 2010-09-10 13:50 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 534 bytes --]
---
TODO | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/TODO b/TODO
index 26f8b84..d41df04 100644
--- a/TODO
+++ b/TODO
@@ -233,7 +233,8 @@ GPRS
Complexity: C2
- Add support for GPRS suspended event. Expose this to the UI by adding a new
- 'Suspended' property on the DataConnectionManager D-Bus interface.
+ 'Suspended' property on the ConnectionManager D-Bus interface.
+ Owner: Mika Liljeberg <mika.liljeberg@nokia.com>
Priority: High
Complexity: C1
--
1.7.0.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] gprs: add Suspended property
2010-09-10 13:50 [PATCH 0/4] Add Suspended property to GPRS (take 3) Mika Liljeberg
2010-09-10 13:50 ` [PATCH 1/4] TODO: Claim ownership of Suspended property for GPRS Mika Liljeberg
@ 2010-09-10 13:50 ` Mika Liljeberg
2010-09-10 13:50 ` [PATCH 3/4] isimodem: implement " Mika Liljeberg
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Mika Liljeberg @ 2010-09-10 13:50 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5382 bytes --]
---
doc/connman-api.txt | 19 +++++++++++++
include/gprs.h | 10 +++++++
src/gprs.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 101 insertions(+), 0 deletions(-)
diff --git a/doc/connman-api.txt b/doc/connman-api.txt
index 43d8897..00d5ed7 100644
--- a/doc/connman-api.txt
+++ b/doc/connman-api.txt
@@ -77,6 +77,25 @@ Properties boolean Attached [readonly]
be available, e.g. receiving SMS over packet radio
or network initiated PDP activation.
+ boolean Suspended [readonly, optional]
+
+ Contains whether the GPRS service is suspended.
+ During suspended state the modem is attached to the
+ GPRS service and all contexts remain established,
+ however, data transfer is not possible.
+
+ The suspended state may be entered if the modem is
+ temporarily out of network coverage. GPRS class B
+ modems will suspend GPRS whenever a voice call is
+ active at the same time. GPRS may also be suspended
+ if the network does not support simultaneous packet
+ data and voice. Various signalling procedures may
+ also cause GPRS to be briefly suspended.
+
+ As the suspension may be brief, clients should wait
+ for an appropriate time for GPRS service to resume
+ before taking corrective action.
+
boolean RoamingAllowed [readwrite]
Contains whether data roaming is allowed. In the off
diff --git a/include/gprs.h b/include/gprs.h
index a1cbcd9..ad7925c 100644
--- a/include/gprs.h
+++ b/include/gprs.h
@@ -47,8 +47,18 @@ struct ofono_gprs_driver {
ofono_gprs_status_cb_t cb, void *data);
};
+enum gprs_suspend_cause {
+ GPRS_SUSPENDED_DETACHED,
+ GPRS_SUSPENDED_SIGNALLING,
+ GPRS_SUSPENDED_CALL,
+ GPRS_SUSPENDED_NO_COVERAGE,
+ GPRS_SUSPENDED_UNKNOWN_CAUSE,
+};
+
void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status);
void ofono_gprs_detached_notify(struct ofono_gprs *gprs);
+void ofono_gprs_suspend_notify(struct ofono_gprs *gprs, int cause);
+void ofono_gprs_resume_notify(struct ofono_gprs *gprs);
int ofono_gprs_driver_register(const struct ofono_gprs_driver *d);
void ofono_gprs_driver_unregister(const struct ofono_gprs_driver *d);
diff --git a/src/gprs.c b/src/gprs.c
index d57115b..d85e70b 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -47,6 +47,7 @@
#define SETTINGS_GROUP "Settings"
#define MAX_CONTEXT_NAME_LENGTH 127
#define MAX_CONTEXTS 256
+#define SUSPEND_TIMEOUT 8
static GSList *g_drivers = NULL;
static GSList *g_context_drivers = NULL;
@@ -64,8 +65,10 @@ struct ofono_gprs {
ofono_bool_t driver_attached;
ofono_bool_t roaming_allowed;
ofono_bool_t powered;
+ ofono_bool_t suspended;
int status;
int flags;
+ guint suspend_timeout;
struct idmap *pid_map;
unsigned int last_context_id;
struct idmap *cid_map;
@@ -894,6 +897,66 @@ static gboolean context_dbus_unregister(struct pri_context *ctx)
OFONO_CONNECTION_CONTEXT_INTERFACE);
}
+static void update_suspended_property(struct ofono_gprs *gprs,
+ ofono_bool_t suspended)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = __ofono_atom_get_path(gprs->atom);
+ dbus_bool_t value = suspended;
+
+ if (gprs->suspend_timeout) {
+ g_source_remove(gprs->suspend_timeout);
+ gprs->suspend_timeout = 0;
+ }
+
+ if (gprs->suspended == suspended)
+ return;
+
+ DBG("%s GPRS service %s", __ofono_atom_get_path(gprs->atom),
+ suspended ? "suspended" : "resumed");
+
+ gprs->suspended = suspended;
+
+ if (gprs->attached)
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_CONNECTION_MANAGER_INTERFACE,
+ "Suspended", DBUS_TYPE_BOOLEAN, &value);
+}
+
+static gboolean suspend_timeout(gpointer data)
+{
+ struct ofono_gprs *gprs = data;
+
+ gprs->suspend_timeout = 0;
+ update_suspended_property(gprs, TRUE);
+ return FALSE;
+}
+
+void ofono_gprs_suspend_notify(struct ofono_gprs *gprs, int cause)
+{
+ switch (cause) {
+ case GPRS_SUSPENDED_DETACHED:
+ case GPRS_SUSPENDED_CALL:
+ case GPRS_SUSPENDED_NO_COVERAGE:
+ update_suspended_property(gprs, TRUE);
+ break;
+
+ case GPRS_SUSPENDED_SIGNALLING:
+ case GPRS_SUSPENDED_UNKNOWN_CAUSE:
+ if (gprs->suspend_timeout)
+ g_source_remove(gprs->suspend_timeout);
+ gprs->suspend_timeout = g_timeout_add_seconds(SUSPEND_TIMEOUT,
+ suspend_timeout,
+ gprs);
+ break;
+ }
+}
+
+void ofono_gprs_resume_notify(struct ofono_gprs *gprs)
+{
+ update_suspended_property(gprs, FALSE);
+}
+
static void gprs_attached_update(struct ofono_gprs *gprs)
{
DBusConnection *conn = ofono_dbus_get_connection();
@@ -1052,6 +1115,12 @@ static DBusMessage *gprs_get_properties(DBusConnection *conn,
value = gprs->powered;
ofono_dbus_dict_append(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value);
+ if (gprs->attached) {
+ value = gprs->suspended;
+ ofono_dbus_dict_append(&dict, "Suspended",
+ DBUS_TYPE_BOOLEAN, &value);
+ }
+
dbus_message_iter_close_container(&iter, &dict);
return reply;
@@ -1697,6 +1766,9 @@ static void gprs_remove(struct ofono_atom *atom)
if (gprs == NULL)
return;
+ if (gprs->suspend_timeout)
+ g_source_remove(gprs->suspend_timeout);
+
if (gprs->pid_map) {
idmap_free(gprs->pid_map);
gprs->pid_map = NULL;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] isimodem: implement Suspended property
2010-09-10 13:50 [PATCH 0/4] Add Suspended property to GPRS (take 3) Mika Liljeberg
2010-09-10 13:50 ` [PATCH 1/4] TODO: Claim ownership of Suspended property for GPRS Mika Liljeberg
2010-09-10 13:50 ` [PATCH 2/4] gprs: add Suspended property Mika Liljeberg
@ 2010-09-10 13:50 ` Mika Liljeberg
2010-09-10 13:50 ` [PATCH 4/4] test: add enable-gprs and disable-gprs scripts Mika Liljeberg
2010-09-10 16:00 ` [PATCH 0/4] Add Suspended property to GPRS (take 3) Denis Kenzior
4 siblings, 0 replies; 6+ messages in thread
From: Mika Liljeberg @ 2010-09-10 13:50 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5685 bytes --]
---
drivers/isimodem/debug.c | 25 ++++++++++++++++++++
drivers/isimodem/debug.h | 2 +
drivers/isimodem/gpds.h | 17 ++++++++++++++
drivers/isimodem/gprs.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 99 insertions(+), 1 deletions(-)
diff --git a/drivers/isimodem/debug.c b/drivers/isimodem/debug.c
index 86530fd..b398797 100644
--- a/drivers/isimodem/debug.c
+++ b/drivers/isimodem/debug.c
@@ -979,6 +979,31 @@ const char *gpds_isi_cause_name(enum gpds_isi_cause value)
return "GPDS_<UNKNOWN>";
}
+const char *gpds_transfer_status_name(enum gpds_transfer_status value)
+{
+ switch (value) {
+ _(GPDS_TRANSFER_NOT_AVAIL);
+ _(GPDS_TRANSFER_AVAIL);
+ }
+ return "GPDS_<UNKNOWN>";
+}
+
+const char *gpds_transfer_cause_name(enum gpds_transfer_cause value)
+{
+ switch (value) {
+ _(GPDS_TRANSFER_CAUSE_ATTACHED);
+ _(GPDS_TRANSFER_CAUSE_DETACHED);
+ _(GPDS_TRANSFER_CAUSE_RESUMED);
+ _(GPDS_TRANSFER_CAUSE_SUSPENDED_NO_COVERAGE);
+ _(GPDS_TRANSFER_CAUSE_SUSPENDED_CALL_SMS);
+ _(GPDS_TRANSFER_CAUSE_SUSPENDED_CALL);
+ _(GPDS_TRANSFER_CAUSE_SUSPENDED_RAU);
+ _(GPDS_TRANSFER_CAUSE_SUSPENDED_LU);
+ _(GPDS_TRANSFER_CAUSE_DSAC_RESTRICTION);
+ }
+ return "GPDS_<UNKNOWN>";
+}
+
#undef _
static void hex_dump(const char *name, const uint8_t m[], size_t len)
diff --git a/drivers/isimodem/debug.h b/drivers/isimodem/debug.h
index d507991..1ad5547 100644
--- a/drivers/isimodem/debug.h
+++ b/drivers/isimodem/debug.h
@@ -70,6 +70,8 @@ const char *gpds_message_id_name(enum gpds_message_id value);
const char *gpds_subblock_name(enum gpds_subblock value);
const char *gpds_status_name(enum gpds_status value);
const char *gpds_isi_cause_name(enum gpds_isi_cause value);
+const char *gpds_transfer_status_name(enum gpds_transfer_status value);
+const char *gpds_transfer_cause_name(enum gpds_transfer_cause value);
void ss_debug(const void *restrict buf, size_t len, void *data);
void mtc_debug(const void *restrict buf, size_t len, void *data);
diff --git a/drivers/isimodem/gpds.h b/drivers/isimodem/gpds.h
index 86d4d95..9bb60e6 100644
--- a/drivers/isimodem/gpds.h
+++ b/drivers/isimodem/gpds.h
@@ -202,6 +202,23 @@ enum gpds_isi_cause {
GPDS_CAUSE_AUT_FAILURE = 0xFF,
};
+enum gpds_transfer_status {
+ GPDS_TRANSFER_NOT_AVAIL = 0x00,
+ GPDS_TRANSFER_AVAIL = 0x01,
+};
+
+enum gpds_transfer_cause {
+ GPDS_TRANSFER_CAUSE_ATTACHED = 0x02,
+ GPDS_TRANSFER_CAUSE_DETACHED = 0x03,
+ GPDS_TRANSFER_CAUSE_RESUMED = 0x04,
+ GPDS_TRANSFER_CAUSE_SUSPENDED_NO_COVERAGE = 0x05,
+ GPDS_TRANSFER_CAUSE_SUSPENDED_CALL_SMS = 0x07,
+ GPDS_TRANSFER_CAUSE_SUSPENDED_CALL = 0x08,
+ GPDS_TRANSFER_CAUSE_SUSPENDED_RAU = 0x09,
+ GPDS_TRANSFER_CAUSE_SUSPENDED_LU = 0x0A,
+ GPDS_TRANSFER_CAUSE_DSAC_RESTRICTION = 0x0B,
+};
+
enum gpds_context_type {
GPDS_CONT_TYPE_NORMAL = 0x00,
GPDS_CONT_TYPE_NWI = 0x01,
diff --git a/drivers/isimodem/gprs.c b/drivers/isimodem/gprs.c
index 6f4f686..93786ec 100644
--- a/drivers/isimodem/gprs.c
+++ b/drivers/isimodem/gprs.c
@@ -72,6 +72,55 @@ static void detach_ind_cb(GIsiClient *client,
/*ofono_gprs_detached_notify(gprs);*/
}
+static void suspend_notify(struct ofono_gprs *gprs, uint8_t suspend_status,
+ uint8_t suspend_cause)
+{
+ int cause;
+
+ DBG("transfer status: %s (0x%02"PRIx8") cause %s (0x%02"PRIx8")",
+ gpds_transfer_status_name(suspend_status), suspend_status,
+ gpds_transfer_cause_name(suspend_cause), suspend_cause);
+
+ if (suspend_status == GPDS_TRANSFER_AVAIL) {
+ ofono_gprs_resume_notify(gprs);
+ return;
+ }
+
+ switch (suspend_cause) {
+ case GPDS_TRANSFER_CAUSE_SUSPENDED_NO_COVERAGE:
+ cause = GPRS_SUSPENDED_NO_COVERAGE;
+ break;
+
+ case GPDS_TRANSFER_CAUSE_SUSPENDED_CALL:
+ cause = GPRS_SUSPENDED_CALL;
+ break;
+
+ case GPDS_TRANSFER_CAUSE_SUSPENDED_CALL_SMS:
+ case GPDS_TRANSFER_CAUSE_SUSPENDED_RAU:
+ case GPDS_TRANSFER_CAUSE_SUSPENDED_LU:
+ cause = GPRS_SUSPENDED_SIGNALLING;
+ break;
+
+ default:
+ return;
+ }
+
+ ofono_gprs_suspend_notify(gprs, cause);
+}
+
+static void transfer_status_ind_cb(GIsiClient *client,
+ const void *restrict data, size_t len,
+ uint16_t object, void *opaque)
+{
+ struct ofono_gprs *gprs = opaque;
+ const unsigned char *msg = data;
+
+ if (!msg || len < 3 || msg[0] != GPDS_TRANSFER_STATUS_IND)
+ return;
+
+ suspend_notify(gprs, msg[1], msg[2]);
+}
+
static gboolean isi_gprs_register(gpointer user)
{
struct ofono_gprs *gprs = user;
@@ -83,6 +132,8 @@ static gboolean isi_gprs_register(gpointer user)
g_isi_client_set_debug(gd->client, gpds_debug, NULL);
g_isi_subscribe(gd->client, GPDS_DETACH_IND, detach_ind_cb, gprs);
+ g_isi_subscribe(gd->client, GPDS_TRANSFER_STATUS_IND,
+ transfer_status_ind_cb, gprs);
ofono_gprs_register(user);
@@ -258,6 +309,7 @@ static gboolean status_resp_cb(GIsiClient *client,
const unsigned char *msg = data;
struct isi_cb_data *cbd = opaque;
ofono_gprs_status_cb_t cb = cbd->cb;
+ struct ofono_gprs *gprs = cbd->data;
int status;
if (!msg) {
@@ -265,7 +317,7 @@ static gboolean status_resp_cb(GIsiClient *client,
goto error;
}
- if (len < 2 || msg[0] != GPDS_STATUS_RESP)
+ if (len < 13 || msg[0] != GPDS_STATUS_RESP)
return FALSE;
/* FIXME: the core still expects reg status, and not a boolean
@@ -281,6 +333,8 @@ static gboolean status_resp_cb(GIsiClient *client,
status = GPRS_STAT_UNKNOWN;
}
+ suspend_notify(gprs, msg[11], msg[12]);
+
CALLBACK_WITH_SUCCESS(cb, status, cbd->data);
return TRUE;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] test: add enable-gprs and disable-gprs scripts
2010-09-10 13:50 [PATCH 0/4] Add Suspended property to GPRS (take 3) Mika Liljeberg
` (2 preceding siblings ...)
2010-09-10 13:50 ` [PATCH 3/4] isimodem: implement " Mika Liljeberg
@ 2010-09-10 13:50 ` Mika Liljeberg
2010-09-10 16:00 ` [PATCH 0/4] Add Suspended property to GPRS (take 3) Denis Kenzior
4 siblings, 0 replies; 6+ messages in thread
From: Mika Liljeberg @ 2010-09-10 13:50 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1492 bytes --]
---
test/disable-gprs | 20 ++++++++++++++++++++
test/enable-gprs | 20 ++++++++++++++++++++
2 files changed, 40 insertions(+), 0 deletions(-)
create mode 100755 test/disable-gprs
create mode 100755 test/enable-gprs
diff --git a/test/disable-gprs b/test/disable-gprs
new file mode 100755
index 0000000..cca2c78
--- /dev/null
+++ b/test/disable-gprs
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+
+import dbus
+import sys
+
+bus = dbus.SystemBus()
+
+if len(sys.argv) == 2:
+ path = sys.argv[1]
+else:
+ manager = dbus.Interface(bus.get_object('org.ofono', '/'),
+ 'org.ofono.Manager')
+ modems = manager.GetModems()
+ path = modems[0][0]
+
+print "Disconnecting GPRS on modem %s..." % path
+cm = dbus.Interface(bus.get_object('org.ofono', path),
+ 'org.ofono.ConnectionManager')
+
+cm.SetProperty("Powered", dbus.Boolean(0))
diff --git a/test/enable-gprs b/test/enable-gprs
new file mode 100755
index 0000000..2b273a7
--- /dev/null
+++ b/test/enable-gprs
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+
+import dbus
+import sys
+
+bus = dbus.SystemBus()
+
+if len(sys.argv) == 2:
+ path = sys.argv[1]
+else:
+ manager = dbus.Interface(bus.get_object('org.ofono', '/'),
+ 'org.ofono.Manager')
+ modems = manager.GetModems()
+ path = modems[0][0]
+
+print "Connecting modem %s..." % path
+cm = dbus.Interface(bus.get_object('org.ofono', path),
+ 'org.ofono.ConnectionManager')
+
+cm.SetProperty("Powered", dbus.Boolean(1))
--
1.7.0.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] Add Suspended property to GPRS (take 3)
2010-09-10 13:50 [PATCH 0/4] Add Suspended property to GPRS (take 3) Mika Liljeberg
` (3 preceding siblings ...)
2010-09-10 13:50 ` [PATCH 4/4] test: add enable-gprs and disable-gprs scripts Mika Liljeberg
@ 2010-09-10 16:00 ` Denis Kenzior
4 siblings, 0 replies; 6+ messages in thread
From: Denis Kenzior @ 2010-09-10 16:00 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1318 bytes --]
Hi Mika,
On 09/10/2010 08:50 AM, Mika Liljeberg wrote:
> Comments from Denis applied.
>
> Br,
>
> MikaL
>
> [PATCH 1/4] TODO: Claim ownership of Suspended property for GPRS
> [PATCH 2/4] gprs: add Suspended property
> [PATCH 3/4] isimodem: implement Suspended property
> [PATCH 4/4] test: add enable-gprs and disable-gprs scripts
>
> TODO | 3 +-
> doc/connman-api.txt | 19 ++++++++++++
> drivers/isimodem/debug.c | 25 ++++++++++++++++
> drivers/isimodem/debug.h | 2 +
> drivers/isimodem/gpds.h | 17 +++++++++++
> drivers/isimodem/gprs.c | 56 +++++++++++++++++++++++++++++++++++-
> include/gprs.h | 10 ++++++
> src/gprs.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
> test/disable-gprs | 20 +++++++++++++
> test/enable-gprs | 20 +++++++++++++
> 10 files changed, 242 insertions(+), 2 deletions(-)
All four patches have been applied. Thanks :)
Just a heads up, when you're adding new files to the project, check to
see whether the build system (Makefile.am) needs to be told about these
files. In this case you forgot to add the two test scripts to
Makefile.am. Running 'make distcheck' whenever new files are added
helps catch most of such issues.
Regards,
-Denis
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-09-10 16:00 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-10 13:50 [PATCH 0/4] Add Suspended property to GPRS (take 3) Mika Liljeberg
2010-09-10 13:50 ` [PATCH 1/4] TODO: Claim ownership of Suspended property for GPRS Mika Liljeberg
2010-09-10 13:50 ` [PATCH 2/4] gprs: add Suspended property Mika Liljeberg
2010-09-10 13:50 ` [PATCH 3/4] isimodem: implement " Mika Liljeberg
2010-09-10 13:50 ` [PATCH 4/4] test: add enable-gprs and disable-gprs scripts Mika Liljeberg
2010-09-10 16:00 ` [PATCH 0/4] Add Suspended property to GPRS (take 3) Denis Kenzior
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.