From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [PATCH 5/8] Internal and Driver API changes for Send USSD
Date: Tue, 14 Sep 2010 12:24:15 -0500 [thread overview]
Message-ID: <4C8FAFBF.1030008@gmail.com> (raw)
In-Reply-To: <1284418817-28575-6-git-send-email-jeevaka.badrappan@elektrobit.com>
[-- Attachment #1: Type: text/plain, Size: 15169 bytes --]
Hi Jeevaka,
On 09/13/2010 06:00 PM, Jeevaka Badrappan wrote:
> ---
> drivers/atmodem/ussd.c | 112 +++++++++++++++++++++++++++--------------------
> drivers/isimodem/ussd.c | 42 +++--------------
> include/ussd.h | 8 ++-
> src/ussd.c | 61 +++++++++++++++++--------
> 4 files changed, 120 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/atmodem/ussd.c b/drivers/atmodem/ussd.c
> index 30145ad..bc5690d 100644
> --- a/drivers/atmodem/ussd.c
> +++ b/drivers/atmodem/ussd.c
> @@ -65,15 +65,17 @@ static void read_charset_cb(gboolean ok, GAtResult *result,
>
> static void cusd_parse(GAtResult *result, struct ofono_ussd *ussd)
> {
> + struct ussd_data *data = ofono_ussd_get_data(ussd);
> GAtResultIter iter;
> int status;
> int dcs;
> - const char *content;
> - char *converted = NULL;
> - gboolean udhi;
> + const char *content = NULL;
> enum sms_charset charset;
> - gboolean compressed;
> - gboolean iso639;
> + unsigned char msg[160];
> + const unsigned char *msg_ptr = NULL;
> + unsigned char *converted = NULL;
> + long written;
> + long msg_len = 0;
>
> g_at_result_iter_init(&iter, result);
>
> @@ -86,34 +88,45 @@ static void cusd_parse(GAtResult *result, struct ofono_ussd *ussd)
> if (!g_at_result_iter_next_string(&iter, &content))
> goto out;
>
> - if (g_at_result_iter_next_number(&iter, &dcs)) {
> - if (!cbs_dcs_decode(dcs, &udhi, NULL, &charset,
> - &compressed, NULL, &iso639))
> - goto out;
> -
> - if (udhi || compressed || iso639)
> - goto out;
> - } else
> - charset = SMS_CHARSET_7BIT;
> -
> - if (charset == SMS_CHARSET_7BIT)
> - converted = convert_gsm_to_utf8((const guint8 *) content,
> - strlen(content), NULL, NULL, 0);
> -
> - else if (charset == SMS_CHARSET_8BIT) {
> - /* TODO: Figure out what to do with 8 bit data */
> - ofono_error("8-bit coded USSD response received");
> - status = 4; /* Not supported */
> - } else {
> - /* No other encoding is mentioned in TS27007 7.15 */
> + if (!g_at_result_iter_next_number(&iter, &dcs))
> + dcs = 0;
> +
> + cbs_dcs_decode(dcs, NULL, NULL, &charset, NULL, NULL, NULL);
> +
> + if (charset == SMS_CHARSET_7BIT) {
> + if (data->charset == AT_UTIL_CHARSET_GSM)
> + msg_ptr = pack_7bit_own_buf((const guint8 *) content,
> + strlen(content), 0, TRUE, &msg_len, 0, msg);
> + else if (data->charset == AT_UTIL_CHARSET_UTF8)
> + ussd_encode(content, &msg_len, msg);
> + else if (data->charset == AT_UTIL_CHARSET_UCS2) {
> + msg_ptr = decode_hex_own_buf(content, -1, &msg_len, 0, msg);
> +
> + converted = convert_ucs2_to_gsm(msg_ptr, msg_len, NULL,
> + &written, 0);
> + if (!converted) {
> + msg_ptr = NULL;
> + msg_len = 0;
> + goto out;
> + }
> +
> + msg_ptr = pack_7bit_own_buf(converted,
> + written, 0, TRUE,
> + &msg_len, 0, msg);
> +
> + g_free(converted);
> + }
> + } else if (charset == SMS_CHARSET_8BIT)
> + msg_ptr = decode_hex_own_buf(content, -1, &msg_len, 0, msg);
> + else if (charset == SMS_CHARSET_UCS2)
> + msg_ptr = decode_hex_own_buf(content, -1, &msg_len, 0, msg);
> + else {
> ofono_error("Unsupported USSD data coding scheme (%02x)", dcs);
> status = 4; /* Not supported */
> }
Can you do me a favor and convert this if statement to a switch/case?
Move the contents of the else clause to the if that checks the DCS. e.g.
if (cbs_dcs_decode() == FALSE) {
....
}
switch (charset)
case SMS_CHARSET_7BIT:
....
case SMS_CHARSET_8BIT:
case SMS_CHARSET_UCS2:
....
>
> out:
> - ofono_ussd_notify(ussd, status, converted);
> -
> - g_free(converted);
> + ofono_ussd_notify(ussd, status, dcs, msg_ptr, msg_len);
> }
>
> static void cusd_request_cb(gboolean ok, GAtResult *result, gpointer user_data)
> @@ -130,39 +143,45 @@ static void cusd_request_cb(gboolean ok, GAtResult *result, gpointer user_data)
> cusd_parse(result, ussd);
> }
>
> -static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
> +static void at_ussd_request(struct ofono_ussd *ussd, int dcs,
> + const unsigned char *pdu, int len,
> ofono_ussd_cb_t cb, void *user_data)
> {
> struct ussd_data *data = ofono_ussd_get_data(ussd);
> struct cb_data *cbd = cb_data_new(cb, user_data);
> - unsigned char *converted = NULL;
> - int dcs;
> - int max_len;
> - long written;
> char buf[256];
> + unsigned char unpacked_buf[182];
> + char coded_buf[160];
> + char *converted;
> + long written;
> + enum sms_charset charset;
>
> if (!cbd)
> goto error;
>
> cbd->user = ussd;
>
> - converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0);
> -
> - if (!converted)
> + if (!cbs_dcs_decode(dcs, NULL, NULL, &charset,
> + NULL, NULL, NULL))
> goto error;
> - else {
> - dcs = 15;
> - max_len = 182;
> - }
>
> - if (written > max_len)
> - goto error;
> + if (charset == SMS_CHARSET_7BIT) {
> + unpack_7bit_own_buf(pdu, len, 0, TRUE, sizeof(unpacked_buf),
> + &written, 0, unpacked_buf);
>
> - snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d",
> - (int) written, converted, dcs);
> + if (written < 1)
> + goto error;
>
> - g_free(converted);
> - converted = NULL;
> + snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d",
> + (int) written, unpacked_buf, dcs);
> + } else {
> + converted = encode_hex_own_buf(pdu, len, 0, coded_buf);
> + if (!converted)
> + goto error;
> +
> + snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d",
> + strlen(converted), converted, dcs);
> + }
>
> if (data->vendor == OFONO_VENDOR_QUALCOMM_MSM) {
> /* Ensure that the modem is using GSM character set. It
> @@ -179,7 +198,6 @@ static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
>
> error:
> g_free(cbd);
> - g_free(converted);
>
> CALLBACK_WITH_FAILURE(cb, user_data);
> }
> diff --git a/drivers/isimodem/ussd.c b/drivers/isimodem/ussd.c
> index 330a141..19ba30e 100644
> --- a/drivers/isimodem/ussd.c
> +++ b/drivers/isimodem/ussd.c
> @@ -74,24 +74,14 @@ static void ussd_parse(struct ofono_ussd *ussd, const void *restrict data,
> {
> const unsigned char *msg = data;
> int status = OFONO_USSD_STATUS_NOT_SUPPORTED;
> - char *converted = NULL;
>
> if (!msg || len < 4)
> - goto out;
> + ofono_ussd_notify(ussd, status, 0, NULL, 0);
>
> status = isi_type_to_status(msg[2]);
>
> if (msg[3] == 0 || (size_t)(msg[3] + 4) > len)
> - goto out;
> -
> - converted = ussd_decode(msg[1], msg[3], msg + 4);
> -
> - if (converted)
> - status = OFONO_USSD_STATUS_NOTIFY;
> -
> -out:
> - ofono_ussd_notify(ussd, status, converted);
> - g_free(converted);
> + ofono_ussd_notify(ussd, status, msg[1], msg + 4, msg[3]);
> }
>
>
> @@ -129,7 +119,7 @@ error:
> }
>
> static GIsiRequest *ussd_send(GIsiClient *client,
> - uint8_t *str, size_t len,
> + int dcs, uint8_t *str, size_t len,
> void *data, GDestroyNotify notify)
> {
> const uint8_t msg[] = {
> @@ -138,7 +128,7 @@ static GIsiRequest *ussd_send(GIsiClient *client,
> 0x01, /* subblock count */
> SS_GSM_USSD_STRING,
> 4 + len + 3, /* subblock length */
> - 0x0f, /* DCS */
> + dcs, /* DCS */
> len, /* string length */
> /* USSD string goes here */
> };
> @@ -152,33 +142,17 @@ static GIsiRequest *ussd_send(GIsiClient *client,
> ussd_send_resp_cb, data, notify);
> }
>
> -static void isi_request(struct ofono_ussd *ussd, const char *str,
> - ofono_ussd_cb_t cb, void *data)
> +static void isi_request(struct ofono_ussd *ussd, int dcs,
> + const unsigned char *pdu, int len,
> + ofono_ussd_cb_t cb, void *data)
> {
> struct ussd_data *ud = ofono_ussd_get_data(ussd);
> struct isi_cb_data *cbd = isi_cb_data_new(ussd, cb, data);
> - unsigned char buf[256];
> - unsigned char *packed = NULL;
> - unsigned char *converted = NULL;
> - long num_packed;
> - long written;
>
> if (!cbd)
> goto error;
>
> - converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0);
> - if (!converted)
> - goto error;
> -
> - packed = pack_7bit_own_buf(converted, written, 0, TRUE,
> - &num_packed, 0, buf);
> -
> - g_free(converted);
> -
> - if (written > SS_MAX_USSD_LENGTH)
> - goto error;
> -
> - if (ussd_send(ud->client, packed, num_packed, cbd, g_free))
> + if (ussd_send(ud->client, dcs, (guint8 *) pdu, len, cbd, g_free))
> return;
>
> error:
> diff --git a/include/ussd.h b/include/ussd.h
> index 96e04cb..360ef00 100644
> --- a/include/ussd.h
> +++ b/include/ussd.h
> @@ -45,13 +45,15 @@ struct ofono_ussd_driver {
> const char *name;
> int (*probe)(struct ofono_ussd *ussd, unsigned int vendor, void *data);
> void (*remove)(struct ofono_ussd *ussd);
> - void (*request)(struct ofono_ussd *ussd, const char *str,
> - ofono_ussd_cb_t, void *data);
> + void (*request)(struct ofono_ussd *ussd, int dcs,
> + const unsigned char *pdu, int len,
> + ofono_ussd_cb_t, void *data);
> void (*cancel)(struct ofono_ussd *ussd,
> ofono_ussd_cb_t cb, void *data);
> };
>
> -void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str);
> +void ofono_ussd_notify(struct ofono_ussd *ussd, int status, int dcs,
> + const unsigned char *data, int data_len);
>
> int ofono_ussd_driver_register(const struct ofono_ussd_driver *d);
> void ofono_ussd_driver_unregister(const struct ofono_ussd_driver *d);
> diff --git a/src/ussd.c b/src/ussd.c
> index fbb07d2..8d9c98d 100644
> --- a/src/ussd.c
> +++ b/src/ussd.c
> @@ -34,8 +34,11 @@
> #include "ofono.h"
>
> #include "common.h"
> +#include "smsutil.h"
> +#include "util.h"
>
> #define SUPPLEMENTARY_SERVICES_INTERFACE "org.ofono.SupplementaryServices"
> +#define MAX_USSD_LENGTH 160
>
> static GSList *g_drivers = NULL;
>
> @@ -317,10 +320,13 @@ static void ussd_change_state(struct ofono_ussd *ussd, int state)
> "State", DBUS_TYPE_STRING, &value);
> }
>
> -void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
> +void ofono_ussd_notify(struct ofono_ussd *ussd, int status, int dcs,
> + const unsigned char *data, int data_len)
> {
> DBusConnection *conn = ofono_dbus_get_connection();
> const char *ussdstr = "USSD";
> + char *utf8_str = NULL;
> + gboolean utf8_str_valid = FALSE;
Please do something like:
char *utf8;
const char *str;
and drop the utf8_str_valid variable
> const char sig[] = { DBUS_TYPE_STRING, 0 };
> DBusMessage *reply;
> DBusMessageIter iter;
> @@ -346,14 +352,20 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
> goto out;
> }
>
> + if (data && data_len > 0)
> + utf8_str = ussd_decode(dcs, data_len, data);
> +
str = utf8;
> + if (!utf8_str) {
> + utf8_str = "";
> + status = OFONO_USSD_STATUS_NOTIFY;
Sorry, I'm not following. Can you explain what is this trying to do?
> + } else
> + utf8_str_valid = TRUE;
> +
> /* TODO: Rework this in the Agent framework */
> if (ussd->state == USSD_STATE_ACTIVE) {
>
> reply = dbus_message_new_method_return(ussd->pending);
>
> - if (!str)
> - str = "";
> -
Leave this in
> dbus_message_iter_init_append(reply, &iter);
>
> dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
> @@ -363,7 +375,7 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
> &variant);
>
> dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING,
> - &str);
> + &utf8_str);
>
> dbus_message_iter_close_container(&iter, &variant);
>
> @@ -375,10 +387,7 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
> } else if (ussd->state == USSD_STATE_RESPONSE_SENT) {
> reply = dbus_message_new_method_return(ussd->pending);
>
> - if (!str)
> - str = "";
> -
> - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
> + dbus_message_append_args(reply, DBUS_TYPE_STRING, &utf8_str,
> DBUS_TYPE_INVALID);
And this
>
> if (status == OFONO_USSD_STATUS_ACTION_REQUIRED)
> @@ -398,20 +407,17 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
> signal_name = "NotificationReceived";
> }
>
> - if (!str)
> - str = "";
> -
> g_dbus_emit_signal(conn, path,
> SUPPLEMENTARY_SERVICES_INTERFACE, signal_name,
> - DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID);
> + DBUS_TYPE_STRING, &utf8_str, DBUS_TYPE_INVALID);
And this
>
> ussd_change_state(ussd, new_state);
> - return;
> + goto free;
> } else {
> ofono_error("Received an unsolicited USSD but can't handle.");
> - DBG("USSD is: status: %d, %s", status, str);
> + DBG("USSD is: status: %d, %s", status, utf8_str);
>
> - return;
> + goto free;
> }
>
> out:
> @@ -419,6 +425,10 @@ out:
>
> dbus_message_unref(ussd->pending);
> ussd->pending = NULL;
> +
> +free:
> + if (utf8_str_valid)
> + g_free(utf8_str);
> }
>
> static void ussd_callback(const struct ofono_error *error, void *data)
> @@ -447,6 +457,9 @@ static DBusMessage *ussd_initiate(DBusConnection *conn, DBusMessage *msg,
> {
> struct ofono_ussd *ussd = data;
> const char *str;
> + int dcs = 0x0f;
> + unsigned char buf[160];
> + long num_packed;
>
> if (ussd->pending)
> return __ofono_error_busy(msg);
> @@ -469,14 +482,17 @@ static DBusMessage *ussd_initiate(DBusConnection *conn, DBusMessage *msg,
> if (!valid_ussd_string(str))
> return __ofono_error_invalid_format(msg);
>
> - DBG("OK, running USSD request");
> + if (!ussd_encode(str, &num_packed, buf))
> + return __ofono_error_invalid_format(msg);
>
> if (!ussd->driver->request)
> return __ofono_error_not_implemented(msg);
>
> + DBG("OK, running USSD request");
> +
> ussd->pending = dbus_message_ref(msg);
>
> - ussd->driver->request(ussd, str, ussd_callback, ussd);
> + ussd->driver->request(ussd, dcs, buf, num_packed, ussd_callback, ussd);
>
> return NULL;
> }
> @@ -507,6 +523,9 @@ static DBusMessage *ussd_respond(DBusConnection *conn, DBusMessage *msg,
> {
> struct ofono_ussd *ussd = data;
> const char *str;
> + int dcs = 0x0f;
> + unsigned char buf[160];
> + long num_packed;
>
> if (ussd->pending)
> return __ofono_error_busy(msg);
> @@ -521,12 +540,16 @@ static DBusMessage *ussd_respond(DBusConnection *conn, DBusMessage *msg,
> if (strlen(str) == 0)
> return __ofono_error_invalid_format(msg);
>
> + if (!ussd_encode(str, &num_packed, buf))
> + return __ofono_error_invalid_format(msg);
> +
> if (!ussd->driver->request)
> return __ofono_error_not_implemented(msg);
>
> ussd->pending = dbus_message_ref(msg);
>
> - ussd->driver->request(ussd, str, ussd_response_callback, ussd);
> + ussd->driver->request(ussd, dcs, buf, num_packed, ussd_response_callback,
> + ussd);
>
> return NULL;
> }
Regards,
-Denis
next prev parent reply other threads:[~2010-09-14 17:24 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-09 12:31 Add support for Send USSD proactive command handling Jeevaka Badrappan
2010-09-09 12:31 ` [PATCH 01/12] atutil changes for parsing cscs query and cscs support Jeevaka Badrappan
2010-09-09 14:45 ` Denis Kenzior
2010-09-09 18:56 ` Jeevaka Badrappan
2010-09-09 18:56 ` [PATCH 01/13] " Jeevaka Badrappan
2010-09-10 17:27 ` Denis Kenzior
2010-09-09 12:31 ` [PATCH 02/12] atgen changes for setting TE character set Jeevaka Badrappan
2010-09-09 14:50 ` Denis Kenzior
2010-09-09 19:00 ` [PATCH 02/13] " Jeevaka Badrappan
2010-09-09 12:31 ` [PATCH 03/12] phonesim " Jeevaka Badrappan
2010-09-09 19:01 ` [PATCH 03/13] " Jeevaka Badrappan
2010-09-10 17:07 ` Denis Kenzior
2010-09-10 20:29 ` [PATCH 2/7] " Jeevaka Badrappan
2010-09-09 12:31 ` [PATCH 04/12] USSD atom driver changes to read current character setting Jeevaka Badrappan
2010-09-09 19:02 ` [PATCH 04/13] " Jeevaka Badrappan
2010-09-09 12:31 ` [PATCH 05/12] Add internal api __ofono_call_barring_is_busy Jeevaka Badrappan
2010-09-09 15:06 ` Denis Kenzior
2010-09-09 12:31 ` [PATCH 06/12] Add internal api __ofono_call_forwarding_is_busy Jeevaka Badrappan
2010-09-09 15:07 ` Denis Kenzior
2010-09-09 12:31 ` [PATCH 07/12] Add internal api __ofono_call_settings_is_busy Jeevaka Badrappan
2010-09-09 15:07 ` Denis Kenzior
2010-09-09 12:31 ` [PATCH 08/12] Add Send USSD command specific result codes Jeevaka Badrappan
2010-09-09 15:09 ` Denis Kenzior
2010-09-09 12:31 ` [PATCH 09/12] Add Send USSD terminal response data structures Jeevaka Badrappan
2010-09-09 15:20 ` Denis Kenzior
2010-09-09 12:31 ` [PATCH 10/12] Add build_dataobj_ussd_text for ussd specific text string handling Jeevaka Badrappan
2010-09-09 15:31 ` Denis Kenzior
2010-09-09 19:06 ` [PATCH 10/13] " Jeevaka Badrappan
2010-09-10 17:29 ` Denis Kenzior
2010-09-10 20:19 ` [PATCH 4/7] " Jeevaka Badrappan
2010-09-10 20:22 ` Denis Kenzior
2010-09-09 12:31 ` [PATCH 11/12] Internal and Driver api changes for Send USSD proactive command Jeevaka Badrappan
2010-09-09 15:59 ` Denis Kenzior
2010-09-09 20:25 ` [PATCH 6/8] " Jeevaka Badrappan
2010-09-09 20:25 ` [PATCH 7/8] Add __ofono_ussd_initiate internal api for Sending USSD Jeevaka Badrappan
2010-09-09 12:31 ` [PATCH 12/12] Handling of Send USSD proactive command Jeevaka Badrappan
2010-09-09 15:37 ` Denis Kenzior
2010-09-09 19:42 ` [PATCH 8/8] " Jeevaka Badrappan
2010-09-13 23:00 ` Added UCS2 handling and review comments incorporated Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 1/8] smsutil: Add USSD encoding function Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 2/8] util: Add UCS2 to GSM 7bit converion function Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 3/8] test-util: Add function for validating UCS2 to GSM bit conversion Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 4/8] USSD atom driver changes to read current character setting Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 5/8] Internal and Driver API changes for Send USSD Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 6/8] Add __ofono_ussd_initiate internal api for Sending USSD Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 7/8] stk: Handling of Send USSD proactive command Jeevaka Badrappan
2010-09-13 23:00 ` [PATCH 8/8] stkutil: Add handling of error case scenario in build USSD data object Jeevaka Badrappan
2010-09-14 21:49 ` [PATCH 3/4] stk: Handling of Send USSD proactive command Jeevaka Badrappan
2010-09-15 17:15 ` Denis Kenzior
2010-09-14 17:45 ` [PATCH 6/8] Add __ofono_ussd_initiate internal api for Sending USSD Denis Kenzior
2010-09-14 21:31 ` [PATCH 2/4] " Jeevaka Badrappan
2010-09-15 17:13 ` Denis Kenzior
2010-09-14 17:24 ` Denis Kenzior [this message]
2010-09-14 21:23 ` [PATCH 1/4] Internal and Driver API changes for Send USSD Jeevaka Badrappan
2010-09-15 17:13 ` Denis Kenzior
2010-09-14 17:01 ` [PATCH 4/8] USSD atom driver changes to read current character setting Denis Kenzior
2010-09-14 17:01 ` [PATCH 3/8] test-util: Add function for validating UCS2 to GSM bit conversion Denis Kenzior
2010-09-14 17:01 ` [PATCH 2/8] util: Add UCS2 to GSM 7bit converion function Denis Kenzior
2010-09-14 16:58 ` [PATCH 1/8] smsutil: Add USSD encoding function Denis Kenzior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C8FAFBF.1030008@gmail.com \
--to=denkenz@gmail.com \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.