From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [RFC PATCH 1/2] smsutil: Status Report assembly
Date: Thu, 10 Jun 2010 11:52:46 -0500 [thread overview]
Message-ID: <201006101152.46861.denkenz@gmail.com> (raw)
In-Reply-To: <1276153545-22260-2-git-send-email-pasi.miettinen@ixonos.com>
[-- Attachment #1: Type: text/plain, Size: 5272 bytes --]
Hi Pasi,
> +void status_report_assembly_free(struct status_report_assembly *assembly)
> +{
> + g_hash_table_destroy(assembly->assembly_table);
You should also be g_freeing the assembly structure itself. In general, it is
a very good idea to run valgrind --leak-check=full on the modified binary
before submitting any patches upstream. This helps to identify such issues
early.
And did I mention unit tests? :)
> +}
> +
> +enum ofono_history_sms_status status_report_assembly_report(
> + struct status_report_assembly *assembly,
> + const struct sms *status_report,
> + unsigned int *msg_id)
> +{
> + unsigned int offset = status_report->status_report.mr / 32;
> + unsigned int bit = 1 << (status_report->status_report.mr % 32);
> + GHashTable *id_table;
> + struct id_table_node *node = NULL;
There's no need to initialize this to NULL.
> + gpointer key;
> + gpointer value;
> + GHashTableIter iter;
> + int i;
> +
> + id_table = g_hash_table_lookup(assembly->assembly_table,
> + status_report->status_report.raddr.address);
> +
> + /* ERROR, key (receiver address) does not exist in assembly*/
> + if (!id_table)
> + return OFONO_HISTORY_SMS_STATUS_ERROR;
> +
> + g_hash_table_iter_init(&iter, id_table);
> + while (g_hash_table_iter_next(&iter, &key, &value)) {
> + node = value;
> +
> + if (!(node->mrs[offset] & bit))
> + continue;
> +
> + if (status_report->status_report.st ==
> + SMS_ST_COMPLETED_RECEIVED) {
> + /* mr belongs to this node */
> + node->mrs[offset] ^= bit;
> + *msg_id = node->ofono_msg_id;
> +
> + for (i = 0; i < 8; i++) {
> + /* There are still pending mr(s). */
> + if (node->mrs[i] != 0)
> + return OFONO_HISTORY_SMS_STATUS_PENDING;
> + }
> + }
> + /* No more pending mrs for this node. Remove node from id_table
> + * and free it.
> + */
> + g_hash_table_iter_remove(&iter);
> + /* id_list empty, remove key and value from assembly_table */
> + if (g_hash_table_size(id_table) == 0)
> + g_hash_table_remove(assembly->assembly_table,
> + status_report->status_report.raddr.address);
> +
> + return OFONO_HISTORY_SMS_STATUS_DELIVERED;
You're marking this message as delivered even if a failure status report was
sent. Also, in the case of a failure, you're not providing the message id.
> +void status_report_assembly_add_fragment(struct status_report_assembly
> + *assembly, unsigned int *msg_id,
Please don't put the assembly on a separate line. The var name should be on
the same line as the type.
msg_id should simply be unsigned int msg_id. This is not an in/out argument.
> + struct sms_address *to,
const struct sms_address *to please.
> + unsigned char mr, time_t expiration)
> +{
> + unsigned int offset = mr / 32;
> + unsigned int bit = 1 << (mr % 32);
> + GHashTable *id_table;
> + struct id_table_node *node;
> + char *assembly_table_key;
> + unsigned int *id_table_key;
> +
> + id_table = g_hash_table_lookup(assembly->assembly_table, to->address);
I'd structure the code like this:
if (id_table == NULL) {
what is in the ... else clause
return;
}
node = g_hash_table_lookup();
if (node) {
return;
}
...
This makes the code much more readable. In general, avoid nested if
statements if possible.
> +
> + if (id_table) {
> + node = g_hash_table_lookup(id_table, msg_id);
> +
> + if (node) {
> + node->mrs[offset] |= bit;
> + node->expiration = expiration;
> + } else {
> + id_table_key = g_new0(unsigned int, 1);
> + node = g_new0(struct id_table_node, 1);
> + node->to = *to;
> + node->ofono_msg_id = *msg_id;
> + node->mrs[offset] |= bit;
> + node->expiration = expiration;
> +
> + *id_table_key = *msg_id;
> + g_hash_table_insert(id_table, id_table_key, node);
> + }
> + } else {
> + id_table = g_hash_table_new_full(g_int_hash, g_int_equal,
> + g_free, g_free);
> + id_table_key = g_new0(unsigned int, 1);
> +
> + node = g_new0(struct id_table_node, 1);
> + node->to = *to;
> + node->ofono_msg_id = *msg_id;
> + node->mrs[offset] |= bit;
> + node->expiration = expiration;
> +
> + *id_table_key = *msg_id;
> + g_hash_table_insert(id_table, id_table_key, node);
> +
> + assembly_table_key = g_try_malloc(sizeof(to->address));
> +
> + if (assembly_table_key == NULL)
> + return;
> +
> + g_strlcpy(assembly_table_key, to->address, sizeof(to->address));
> +
> + g_hash_table_insert(assembly->assembly_table,
> + assembly_table_key, id_table);
> + }
I see one problem with this function, namely that under some bizarre
circumstances, the status report might come back before additional fragments
have been added. So this function should also take a num_fragments argument
and keep track of how many fragment status reports were actually received.
This gets a bit tricky when a failure is reported before the entire set of
fragments has been submitted...
> +struct id_table_node {
> + struct sms_address to;
> + unsigned int ofono_msg_id;
Why are you storing the message id when it is also the key for the hash table?
> + unsigned int mrs[8];
> + time_t expiration;
> +};
> +
Regards,
-Denis
next prev parent reply other threads:[~2010-06-10 16:52 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-10 7:05 SMS status report Pasi Miettinen
2010-06-10 7:05 ` [RFC PATCH 1/2] smsutil: Status Report assembly Pasi Miettinen
2010-06-10 7:05 ` [RFC PATCH 2/2] sms: status report notify Pasi Miettinen
2010-06-10 15:07 ` Denis Kenzior
2010-06-10 16:14 ` Denis Kenzior
2010-06-10 16:52 ` Denis Kenzior [this message]
2010-06-11 11:35 ` VS: [RFC PATCH 1/2] smsutil: Status Report assembly Miettinen Pasi
2010-06-11 12:23 ` Miettinen Pasi
2010-06-10 14:47 ` SMS status report 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=201006101152.46861.denkenz@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.