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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox