From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [RFC_PATCH 2/4] smsutil: Editorial changes to sms status report function
Date: Tue, 17 Aug 2010 13:10:33 -0500 [thread overview]
Message-ID: <4C6AD099.2080708@gmail.com> (raw)
In-Reply-To: <1281942533-9126-2-git-send-email-petteri.tikander@ixonos.com>
[-- Attachment #1: Type: text/plain, Size: 9858 bytes --]
Hi Petteri,
On 08/16/2010 02:08 AM, Petteri Tikander wrote:
> ---
> src/smsutil.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 198 insertions(+), 4 deletions(-)
>
Can we change the commit message a bit, something about storing /
loading sms status report assemblies over reboots ;)
> diff --git a/src/smsutil.c b/src/smsutil.c
> index 22c70cf..0972988 100644
> --- a/src/smsutil.c
> +++ b/src/smsutil.c
> @@ -45,6 +45,10 @@
> #define SMS_BACKUP_PATH_DIR SMS_BACKUP_PATH "/%s-%i-%i"
> #define SMS_BACKUP_PATH_FILE SMS_BACKUP_PATH_DIR "/%03i"
>
> +#define SMS_SR_BACKUP_PATH STORAGEDIR "/%s/sms_sr"
> +#define SMS_SR_BACKUP_PATH_DIR SMS_SR_BACKUP_PATH "/%s-%i-%i"
> +#define SMS_SR_BACKUP_PATH_FILE SMS_SR_BACKUP_PATH_DIR "/%i"
> +
> #define SMS_ADDR_FMT "%24[0-9A-F]"
>
> static GSList *sms_assembly_add_fragment_backup(struct sms_assembly *assembly,
> @@ -2642,20 +2646,204 @@ void sms_assembly_expire(struct sms_assembly *assembly, time_t before)
> }
> }
>
> +static void sr_assembly_load_backup(GHashTable *assembly_table,
> + const char *imsi,
> + const struct dirent *addr_dir)
> +{
> + char *path;
> + struct dirent **ids;
> + struct sms_address sms_addr, *addr;
> + struct id_table_node *node;
> + GHashTable *id_table;
> + int len;
> + int r;
> + unsigned char buf[sizeof(node->mrs) + sizeof(node->total_mrs) +
> + sizeof(node->sent_mrs) + sizeof(node->deliverable)];
> + char *assembly_table_key;
> + unsigned int *id_table_key;
> + struct stat segment_stat;
> +
> + if (addr_dir->d_type != DT_DIR)
> + return;
> +
> + addr = &sms_addr;
> +
> + if (sscanf(addr_dir->d_name, SMS_ADDR_FMT "-%i-%i",
> + addr->address, (int *) &addr->number_type,
> + (int *) &addr->numbering_plan) < 3) {
> + return;
> + }
Lets follow what the sms_assembly does here. Namely SMS_ADDR_FMT is
actually geared towards a hex-encoded address. This already contains
the address, number_type and numbering_plan elements. So simply using
sms_assembly_extract_address() afterwards is actually fine. This has
the advantage of getting rid of the unnecessary casts.
> +
> + /* Go through different msg_ids. */
> + path = g_strdup_printf(SMS_SR_BACKUP_PATH "/%s", imsi,
> + addr_dir->d_name);
> + len = scandir(path, &ids, NULL, versionsort);
> +
> + g_free(path);
> +
> + if (len < 0)
> + return;
> +
> + id_table = g_hash_table_new_full(g_int_hash, g_int_equal,
> + g_free, g_free);
> +
> + assembly_table_key = g_try_malloc(sizeof(addr->address));
> +
> + if (assembly_table_key == NULL)
> + return;
> +
> + g_strlcpy(assembly_table_key, addr->address, sizeof(addr->address));
> + g_hash_table_insert(assembly_table, assembly_table_key, id_table);
> +
> + while (len--) {
> + path = g_strdup_printf(SMS_SR_BACKUP_PATH "/%s/%s",
> + imsi, addr_dir->d_name, ids[len]->d_name);
> + r = read_file(buf, sizeof(buf), SMS_SR_BACKUP_PATH "/%s/%s",
> + imsi, addr_dir->d_name, ids[len]->d_name);
> +
> + if (r < 0) {
> + g_free(path);
> + g_free(ids[len]);
> + continue;
> + }
> +
> + r = stat(path, &segment_stat);
> +
> + if (r != 0) {
> + g_free(path);
> + g_free(ids[len]);
> + continue;
> + }
> + /* Gather the data for id_table node */
> + node = g_new0(struct id_table_node, 1);
> + memcpy(&node->to, addr, sizeof(*addr));
So I got rid of the node->to for now. There's no reason to have it that
I can see... Any time you are building / loading / accessing a node,
you actually know the current to address anyway.
> + node->expiration = segment_stat.st_mtime;
> + memcpy(node->mrs, buf, sizeof(node->mrs));
> + memcpy(&node->total_mrs, buf + sizeof(node->mrs),
> + sizeof(node->total_mrs));
> + memcpy(&node->sent_mrs,
> + buf + sizeof(node->mrs) + sizeof(node->total_mrs),
> + sizeof(node->sent_mrs));
> +
> + memcpy(&node->deliverable, buf + sizeof(node->mrs) +
> + sizeof(node->total_mrs) + sizeof(node->sent_mrs),
> + sizeof(node->deliverable));
To make our lives easier, I'd make the id_table_node structure packed
and read the data directly into it. We don't have to worry about
byte-ordering at this point.
> + /* Node ready, create key and add them to the table */
> + id_table_key = g_new0(unsigned int, 1);
> + *id_table_key = atoi(ids[len]->d_name);
> +
> + g_hash_table_insert(id_table, id_table_key, node);
> +
> + g_free(path);
> + g_free(ids[len]);
> + }
> + g_free(ids);
> +}
> +
> struct status_report_assembly *status_report_assembly_new(const char *imsi)
> {
> + char *path;
> + int len;
> + struct dirent **addresses;
> struct status_report_assembly *ret =
> g_new0(struct status_report_assembly, 1);
>
> ret->assembly_table = g_hash_table_new_full(g_str_hash, g_str_equal,
> g_free, (GDestroyNotify)g_hash_table_destroy);
>
> - if (imsi)
> + if (imsi) {
> ret->imsi = imsi;
>
> + /* Restore state from backup */
> + path = g_strdup_printf(SMS_SR_BACKUP_PATH, imsi);
> + len = scandir(path, &addresses, NULL, alphasort);
> +
> + g_free(path);
> +
> + if (len < 0)
> + return ret;
> +
> + /* Go through different addresses. Each address can relate to
> + * 1-n msg_ids.
> + */
> +
> + while (len--) {
> + sr_assembly_load_backup(ret->assembly_table, imsi,
> + addresses[len]);
> + g_free(addresses[len]);
> + }
> +
> + g_free(addresses);
> + }
> +
This looks just fine to me.
> return ret;
> }
>
> +static gboolean sr_assembly_add_fragment_backup(const char *imsi,
> + const struct id_table_node *node,
> + unsigned int msg_id)
> +{
> + int len = sizeof(node->mrs) + sizeof(node->total_mrs) +
> + sizeof(node->sent_mrs) + sizeof(node->deliverable);
> + unsigned char buf[len];
> +
> + if (!imsi)
> + return FALSE;
> +
> + memcpy(buf, node->mrs, sizeof(node->mrs));
> +
> + memcpy(buf + sizeof(node->mrs), &node->total_mrs,
> + sizeof(node->total_mrs));
> +
> + memcpy(buf + sizeof(node->mrs) + sizeof(node->total_mrs),
> + &node->sent_mrs, sizeof(node->sent_mrs));
> +
> + memcpy(buf + sizeof(node->mrs) + sizeof(node->total_mrs) +
> + sizeof(node->sent_mrs), &node->deliverable, sizeof(node->deliverable));
> +
Again, simply writing the id_table_node structure might be easier here,
especially since you're not taking care of loading the expiration member.
> + /* storagedir/%s/sms_sr/%s-%i-%i/%i */
> + if (write_file(buf, len, SMS_BACKUP_MODE, SMS_SR_BACKUP_PATH_FILE, imsi,
> + node->to.address, node->to.number_type,
> + node->to.numbering_plan, msg_id) != len)
> + return FALSE;
> +
> + return TRUE;
> +}
> +
> +static gboolean sr_assembly_remove_fragment_backup(const char *imsi,
> + const struct id_table_node *node,
> + unsigned int msg_id)
> +{
> + char *path;
> +
> + if (!imsi)
> + return FALSE;
> +
> + path = g_strdup_printf(SMS_SR_BACKUP_PATH_FILE, imsi, node->to.address,
> + node->to.number_type, node->to.numbering_plan,
> + msg_id);
> +
> + unlink(path);
> + g_free(path);
> +
> + path = g_strdup_printf(SMS_SR_BACKUP_PATH_DIR, imsi, node->to.address,
> + node->to.number_type, node->to.numbering_plan);
> +
> + /* If the address does not have relating msg_ids anymore, remove it */
> + rmdir(path);
> + g_free(path);
> +
> + return TRUE;
> +}
> +
> +static gboolean sr_assembly_update_fragment_backup(const char *imsi,
> + const struct id_table_node *node,
> + unsigned int msg_id)
> +{
> + return sr_assembly_remove_fragment_backup(imsi, node, msg_id) &&
> + sr_assembly_add_fragment_backup(imsi, node, msg_id);
> +}
> +
> void status_report_assembly_free(struct status_report_assembly *assembly)
> {
> g_hash_table_destroy(assembly->assembly_table);
> @@ -2714,7 +2902,6 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
> g_hash_table_iter_init(&iter, id_table);
> while (g_hash_table_iter_next(&iter, &key, &value)) {
> node = value;
> -
Leave this empty line here, remember to check doc/coding-style.txt for a
reason why.
> if (node->mrs[offset] & bit)
> break;
>
> @@ -2724,7 +2911,6 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
> /* Unable to find a message reference belonging to this address */
> if (node == NULL)
> return FALSE;
> -
Same comment as above.
> /* Mr belongs to this node. */
> node->mrs[offset] ^= bit;
>
> @@ -2743,8 +2929,12 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
> }
> }
>
> - if (pending == TRUE && node->deliverable == TRUE)
> + if (pending == TRUE && node->deliverable == TRUE) {
> + sr_assembly_add_fragment_backup(assembly->imsi, node,
> + *((unsigned int *) key));
> +
> return FALSE;
> + }
>
> if (out_delivered)
> *out_delivered = node->deliverable;
> @@ -2752,6 +2942,9 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
> if (out_id)
> *out_id = *((unsigned int *) key);
>
> + sr_assembly_remove_fragment_backup(assembly->imsi, node,
> + *((unsigned int *) key));
> +
Honestly I'd like to see the cast done once and then used everywhere
afterwards. Feel free to add an extra variable for this.
> g_hash_table_iter_remove(&iter);
>
> if (g_hash_table_size(id_table) == 0)
> @@ -2805,6 +2998,7 @@ void status_report_assembly_add_fragment(
> node->mrs[offset] |= bit;
> node->expiration = expiration;
> node->sent_mrs++;
> + sr_assembly_add_fragment_backup(assembly->imsi, node, msg_id);
> }
>
> void status_report_assembly_expire(struct status_report_assembly *assembly,
Regards,
-Denis
next prev parent reply other threads:[~2010-08-17 18:10 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1281942533-9126-1-git-send-email-petteri.tikander@ixonos.com>
2010-08-16 7:08 ` [RFC_PATCH 2/4] smsutil: Editorial changes to sms status report function Petteri Tikander
2010-08-16 7:08 ` [RFC_PATCH 3/4] smsutil:add proper checking of sms-address in status report-function Petteri Tikander
2010-08-16 7:08 ` [RFC_PATCH 4/4] smsutil: added function for data handling of status report Petteri Tikander
2010-08-17 19:07 ` Denis Kenzior
2010-08-18 17:53 ` Petteri Tikander
2010-08-18 18:11 ` Denis Kenzior
2010-08-17 18:16 ` [RFC_PATCH 3/4] smsutil:add proper checking of sms-address in status report-function Denis Kenzior
2010-08-17 18:10 ` Denis Kenzior [this message]
2010-08-18 17:40 ` [RFC_PATCH 2/4] smsutil: Editorial changes to sms status report function Petteri Tikander
2010-08-18 18:09 ` 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=4C6AD099.2080708@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