Merge lp:~awe/phablet-extras/ofono-unittest-gprs-context into lp:phablet-extras/ofono

Proposed by Tony Espy
Status: Merged
Approved by: Ricardo Salveti
Approved revision: 67
Merged at revision: 48
Proposed branch: lp:~awe/phablet-extras/ofono-unittest-gprs-context
Merge into: lp:phablet-extras/ofono
Diff against target: 2756 lines (+1901/-394)
20 files modified
Makefile.am (+23/-2)
drivers/rilmodem/gprs-context.c (+187/-260)
drivers/rilmodem/rilutil.c (+2/-81)
drivers/rilmodem/rilutil.h (+0/-13)
gril/gril.c (+19/-6)
gril/gril.h (+10/-8)
gril/grilreply.c (+225/-0)
gril/grilreply.h (+57/-0)
gril/grilrequest.c (+213/-0)
gril/grilrequest.h (+63/-0)
gril/grilunsol.c (+158/-0)
gril/grilunsol.h (+62/-0)
gril/grilutil.c (+47/-0)
gril/grilutil.h (+9/-5)
gril/parcel.c (+15/-19)
gril/ril_constants.h (+12/-0)
include/types.h (+10/-0)
unit/test-grilreply.c (+339/-0)
unit/test-grilrequest.c (+312/-0)
unit/test-grilunsol.c (+138/-0)
To merge this branch: bzr merge lp:~awe/phablet-extras/ofono-unittest-gprs-context
Reviewer Review Type Date Requested Status
Ricardo Salveti (community) Approve
PS Jenkins bot continuous-integration Approve
Sergio Schvezov Needs Fixing
Review via email: mp+173558@code.launchpad.net

Commit message

[gril/rilmodem] Re-factor gprs-context code to facilitate unit testing.

Description of the change

This branch re-factors rilmodem's gprs-context module such that all RIL message code has been moved into the lower gril base layer. This was done to allow unit testing of the RIL parcel code used by gprs-context.

Once this code has been merged, the plan is to re-factor the rest of the rilmodem code using this approach.

Tested on an un-flipped raring image running on maguro.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tony Espy (awe) wrote :

Build failure is due to the fact that I didn't add the unit test source file... I'm working on restoring it, and should have this branch updated by end-of-day.

54. By Tony Espy

[gril] Re-work of gprsmessages based on unit testing.

55. By Tony Espy

[gril] Initial gprs-context unit tests for grilmessages.

56. By Tony Espy

[gril] Make changes for unit testing.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

I would split:
823 +static void test_invalid_setup_data_calls(void)
834 + /* Test invalid radio tech values */
847 + /* Test invalid data profile */
855 + /* Invalid APNs */
...
and so on for the other test functions into individual test cases.

Also consider the posibility of a test fixture for each of these test functions(at your discretion)
https://developer.gnome.org/glib/2.28/glib-Testing.html#g-test-add

Is it a good idea to make a free_reply (or with similar name) that would take care of freeing the complete struct and then just call that?
238 + g_strfreev(reply.dns_addresses);
239 + g_strfreev(reply.ip_addrs);
240 + g_strfreev(reply.gateways);
249 + g_free(reply.ifname);

review: Needs Fixing
Revision history for this message
Tony Espy (awe) wrote :

@Sergio

Thanks for the comments, and I agree that splitting the tests out probably makes sense.

Also per our discussion yesterday, I will split grilmessages.c into three separate files: grilrequests.c, grilreplies.c, and grilevents.c.

Finally, I also mentioned that I only added unit tests for the SETUP_DATA_CALL request. I will go ahead and add unit tests for the corresponding reply as well.

I should be able to wrap up all these changes today.

Revision history for this message
Sergio Schvezov (sergiusens) wrote :

On Fri, Jul 12, 2013 at 12:15 PM, Tony Espy <email address hidden> wrote:
> @Sergio
>
> Thanks for the comments, and I agree that splitting the tests out probably makes sense.
>
> Also per our discussion yesterday, I will split grilmessages.c into three separate files: grilrequests.c, grilreplies.c, and grilevents.c.
>
> Finally, I also mentioned that I only added unit tests for the SETUP_DATA_CALL request. I will go ahead and add unit tests for the corresponding reply as well.
>
> I should be able to wrap up all these changes today.

Sounds good to me :-)

57. By Tony Espy

[gril/rilmodem] Split grilmessages into grilrequest, grilreply, and grilunsol.

58. By Tony Espy

[rilmodem] Back out AudioSystem and Makefile.am changes made by mistake.

59. By Tony Espy

[gril] Re-factored low-level message support into type-specific modules.

60. By Tony Espy

[gril] Fixed the tracing logic, and cleaned up some minor warnings.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
61. By Tony Espy

Re-merge from trunk.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tony Espy (awe) wrote :

Two last things need to be fixed.

First, the CI build fails due to a unit test failure. This is the test I mentioned earlier that was also failing in pbuild.

ERROR:unit/test-grilrequest.c:200:test_deactivate_data_call_valid: assertion failed: (!memcmp(rilp.data, test_data->parcel_data, test_data->parcel_size)\

Test test tries to compare wire-format parcel data ( stored in rilp.data ) to a static guchar of bytes that represent what the parcel wire format should look like.

The second issue is how the gprs-context code handles setup_data_call failures. I'm not sure if a failure callback triggers a disconnect from the core ofono code or not. If it does, then the code should be fine as is. If it doesn't, then this could potentially leave an active data call within RIL, and thus we should explicitly disconnect in this case.

Revision history for this message
Tony Espy (awe) wrote :

OK, so it appears the failure callback doesn't trigger a disconnect, so I'll modify the code to do that if the SETUP_DATA_CALL reply triggers a message validation error.

Revision history for this message
Tony Espy (awe) wrote :

I'll plan on landing the final bits over the weekend...

62. By Tony Espy

[gril/grilmodem] Ensure that data call is deactivated in invalid reply scenarios.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
63. By Tony Espy

[gril] Fix a bug in parcel_w_string() that can cause an invalid string terminator to be generated.

Revision history for this message
Tony Espy (awe) wrote :

OK, both problems are now fixed.

Data calls are properly disconnected if a reply is received from RIL that is deemed invalid by the gril code.

The unit test failure was due to a subtle bug in parcel_w_string() which could result in invalid string terminator bytes to be included due to an incorrect offset used to write the terminating utf16 0x00000.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
64. By Tony Espy

[rilmodem] Implement gprs_context_detach_shutdown().

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

127 - if (message->req != RIL_UNSOL_DATA_CALL_LIST_CHANGED) {
128 - ofono_error("ril_gprs_update_calls: invalid message received %d",
129 - message->req);
130 - return;
131 - }

Why did you remove the above? g_ril_unsol_parse_data_call_list is also not checking if the message is indeed UNSOL_DATA_CALL_LIST_CHANGED.

1017 + g_free(reply);
1611 + g_free(call);
1621 + g_free(unsol);

Not an issue, but as you're checking for call and unsol just before free, you could include the g_free call as part of the if scope.

901 +#define OFONO_EINVAL(error) do { \
902 + error->type = OFONO_ERROR_TYPE_FAILURE; \
903 + error->error = -EINVAL; \
904 +} while (0)
905 +
906 +#define OFONO_NO_ERROR(error) do { \
907 + error->type = OFONO_ERROR_TYPE_NO_ERROR; \
908 + error->error = 0; \
909 +} while (0)
910 +

These would be better if defined somewhere in a common ofono code, not just for ril.

2018 +static const struct ril_msg reply_data_call_invalid_2 = {
2019 + .buf = (gchar *) &reply_data_call_invalid_parcel1,

2052 +static const struct ril_msg reply_data_call_invalid_3 = {
2053 + .buf = (gchar *) &reply_data_call_invalid_parcel2,

2084 +static const struct ril_msg reply_data_call_invalid_4 = {
2085 + .buf = (gchar *) &reply_data_call_invalid_parcel3,

2115 +static const struct ril_msg reply_data_call_invalid_5 = {
2116 + .buf = (gchar *) &reply_data_call_invalid_parcel4,

2147 +static const struct ril_msg reply_data_call_invalid_6 = {
2148 + .buf = (gchar *) &reply_data_call_invalid_parcel5,

2176 +static const struct ril_msg reply_data_call_invalid_7 = {
2177 + .buf = (gchar *) &reply_data_call_invalid_parcel6,

Would you mind changing the test id to match the same number used by both structs? Otherwise it gets quite confusing when reading the code, as data_call_invalid_2 is part of invalid_parcel_1, instead of invalid_parcel_2 (which is a natural reading by our brain).

Other than those minor comments, code looks good (although it could technically be separated in more MRs, as we discussed).

Will now test in both mako and maguro.

review: Needs Fixing
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Tested with both mako and maguro and it seems to be all good :-)

Just minor issue I got with my maguro is that the modem can't attach anymore it seems, but don't think it's related with this MR (might be that intermittent issue we had this week).

Will test a bit more with maguro...

Would be nice if you could double check with it as well.

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Yeah, can't get my mako to attach anymore, with/without NM, and even after a clean install.

We might be having another issue somewhere in this code, which is not related with this MR.

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Argh, *maguro*.

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Ok, the issue with maguro is that it cannot attach at first, but it works after restarting ofono =\

First run, not attached:
http://paste.ubuntu.com/5917341/

Second run, attached:
http://paste.ubuntu.com/5917346/

Wonder if this is a side effect of that roaming bug you fixed (will follow up this in a bug).

Revision history for this message
Tony Espy (awe) wrote :

Question, were you testing with just this MR, or the combined MRs? As we discussed, the attach fix was split between the two MRs due to the heavy re-factoring of gprs-context.c in this MR.

I will look at your comments above, which all seem reasonable and try and update the MR later today.

I will also do some more testing to see if I can reproduce any of the issues you ran into while testing.

Note, my fix assumes that NetworkManager always sets the ConnectionManager's 'Powered' on start-up. Perhaps there's a race condition and this isn't always happening?

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Just with this MR, and without NetworkManager involved. Was just tracking the ofono state after it was properly initialized.

Revision history for this message
Tony Espy (awe) wrote :

OK, I'll plan on giving both a shake-down tomorrow after I clean up the couple of things based on your previous comment.

This code really shouldn't have effected whether GPRS attaches or not, as it only touches the gprs-context driver.

65. By Tony Espy

[gril] Moved ofono error helper #defines into <ofono/types.h>

66. By Tony Espy

[gril] Re-numbered parcel unit test data variables to match test cases.

67. By Tony Espy

[gril] Minor re-factoring in helper functions.

Revision history for this message
Tony Espy (awe) wrote :

> 127 - if (message->req != RIL_UNSOL_DATA_CALL_LIST_CHANGED) {
> 128 - ofono_error("ril_gprs_update_calls: invalid message received %d",
> 129 - message->req);
> 130 - return;
> 131 - }
>
> Why did you remove the above? g_ril_unsol_parse_data_call_list is also not
> checking if the message is indeed UNSOL_DATA_CALL_LIST_CHANGED.

I removed it because it wasn't needed. If you look at the code in gril.c that handles unsolicited messages, it's not really possible for the wrong message to be passed to a registered listener, as that's the whole purpose of registering for a particular message.

> 1017 + g_free(reply);
> 1611 + g_free(call);
> 1621 + g_free(unsol);
>
> Not an issue, but as you're checking for call and unsol just before free, you
> could include the g_free call as part of the if scope.

Done.

> 901 +#define OFONO_EINVAL(error) do { \
> 902 + error->type = OFONO_ERROR_TYPE_FAILURE; \
> 903 + error->error = -EINVAL; \
> 904 +} while (0)
> 905 +
> 906 +#define OFONO_NO_ERROR(error) do { \
> 907 + error->type = OFONO_ERROR_TYPE_NO_ERROR; \
> 908 + error->error = 0; \
> 909 +} while (0)
> 910 +
>
> These would be better if defined somewhere in a common ofono code, not just
> for ril.

Done, moved these to <ofono/type.h>.
>
> 2018 +static const struct ril_msg reply_data_call_invalid_2 = {
> 2019 + .buf = (gchar *) &reply_data_call_invalid_parcel1,
>
> 2052 +static const struct ril_msg reply_data_call_invalid_3 = {
> 2053 + .buf = (gchar *) &reply_data_call_invalid_parcel2,
>
> 2084 +static const struct ril_msg reply_data_call_invalid_4 = {
> 2085 + .buf = (gchar *) &reply_data_call_invalid_parcel3,
>
> 2115 +static const struct ril_msg reply_data_call_invalid_5 = {
> 2116 + .buf = (gchar *) &reply_data_call_invalid_parcel4,
>
> 2147 +static const struct ril_msg reply_data_call_invalid_6 = {
> 2148 + .buf = (gchar *) &reply_data_call_invalid_parcel5,
>
> 2176 +static const struct ril_msg reply_data_call_invalid_7 = {
> 2177 + .buf = (gchar *) &reply_data_call_invalid_parcel6,
>
> Would you mind changing the test id to match the same number used by both
> structs? Otherwise it gets quite confusing when reading the code, as
> data_call_invalid_2 is part of invalid_parcel_1, instead of invalid_parcel_2
> (which is a natural reading by our brain).

Yea, I thought about this an since the first test case didn't actually have parcel_data, I thought it would be weird having the first parcel data variable start with "2". Oh well, not a big deal. Re-number per your suggestion.

> Other than those minor comments, code looks good (although it could
> technically be separated in more MRs, as we discussed).
>
> Will now test in both mako and maguro.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Good, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile.am'
--- Makefile.am 2013-06-18 00:13:38 +0000
+++ Makefile.am 2013-07-28 19:18:23 +0000
@@ -93,7 +93,10 @@
93 gril/grilio.c gril/grilutil.h \93 gril/grilio.c gril/grilutil.h \
94 gril/grilutil.c gril/ringbuffer.h \94 gril/grilutil.c gril/ringbuffer.h \
95 gril/gfunc.h gril/ril.h \95 gril/gfunc.h gril/ril.h \
96 gril/parcel.c gril/parcel.h96 gril/parcel.c gril/parcel.h \
97 gril/grilreply.c gril/grilreply.h \
98 gril/grilrequest.c gril/grilrequest.h \
99 gril/grilunsol.c gril/grilunsol.h
97100
98btio_sources = btio/btio.h btio/btio.c101btio_sources = btio/btio.h btio/btio.c
99102
@@ -684,7 +687,10 @@
684687
685unit_tests = unit/test-common unit/test-util unit/test-idmap \688unit_tests = unit/test-common unit/test-util unit/test-idmap \
686 unit/test-simutil unit/test-stkutil \689 unit/test-simutil unit/test-stkutil \
687 unit/test-sms unit/test-cdmasms690 unit/test-sms unit/test-cdmasms \
691 unit/test-grilrequest \
692 unit/test-grilreply \
693 unit/test-grilunsol
688694
689noinst_PROGRAMS = $(unit_tests) \695noinst_PROGRAMS = $(unit_tests) \
690 unit/test-sms-root unit/test-mux unit/test-caif696 unit/test-sms-root unit/test-mux unit/test-caif
@@ -736,6 +742,21 @@
736unit_test_caif_LDADD = @GLIB_LIBS@742unit_test_caif_LDADD = @GLIB_LIBS@
737unit_objects += $(unit_test_caif_OBJECTS)743unit_objects += $(unit_test_caif_OBJECTS)
738744
745unit_test_grilrequest_SOURCES = unit/test-grilrequest.c $(gril_sources) \
746 src/log.c gatchat/ringbuffer.c
747unit_test_grilrequest_LDADD = @GLIB_LIBS@
748unit_objects += $(unit_test_grilrequest_OBJECTS)
749
750unit_test_grilreply_SOURCES = unit/test-grilreply.c $(gril_sources) \
751 src/log.c gatchat/ringbuffer.c
752unit_test_grilreply_LDADD = @GLIB_LIBS@
753unit_objects += $(unit_test_grilreply_OBJECTS)
754
755unit_test_grilunsol_SOURCES = unit/test-grilunsol.c $(gril_sources) \
756 src/log.c gatchat/ringbuffer.c
757unit_test_grilunsol_LDADD = @GLIB_LIBS@
758unit_objects += $(unit_test_grilunsol_OBJECTS)
759
739TESTS = $(unit_tests)760TESTS = $(unit_tests)
740761
741if TOOLS762if TOOLS
742763
=== modified file 'drivers/rilmodem/gprs-context.c'
--- drivers/rilmodem/gprs-context.c 2013-06-13 14:59:09 +0000
+++ drivers/rilmodem/gprs-context.c 2013-07-28 19:18:23 +0000
@@ -38,23 +38,12 @@
38#include <ofono/gprs-context.h>38#include <ofono/gprs-context.h>
39#include <ofono/types.h>39#include <ofono/types.h>
4040
41#include "gril.h"41#include "grilreply.h"
42#include "grilutil.h"42#include "grilrequest.h"
43#include "grilunsol.h"
4344
44#include "rilmodem.h"45#include "rilmodem.h"
4546
46/* REQUEST_DEACTIVATE_DATA_CALL parameter values */
47#define DEACTIVATE_DATA_CALL_NUM_PARAMS 2
48#define DEACTIVATE_DATA_CALL_NO_REASON "0"
49
50/* REQUEST_SETUP_DATA_CALL parameter values */
51#define SETUP_DATA_CALL_PARAMS 7
52#define CHAP_PAP_OK "3"
53#define DATA_PROFILE_DEFAULT "0"
54#define PROTO_IP "IP"
55#define PROTO_IPV6 "IPV6"
56#define PROTO_IPV4V6 "IPV4V6"
57
58enum state {47enum state {
59 STATE_IDLE,48 STATE_IDLE,
60 STATE_ENABLING,49 STATE_ENABLING,
@@ -64,36 +53,51 @@
6453
65struct gprs_context_data {54struct gprs_context_data {
66 GRil *ril;55 GRil *ril;
67 unsigned int active_ctx_cid;56 guint active_ctx_cid;
68 unsigned int active_rild_cid;57 gint active_rild_cid;
69 char username[OFONO_GPRS_MAX_USERNAME_LENGTH + 1];
70 char password[OFONO_GPRS_MAX_PASSWORD_LENGTH + 1];
71 enum state state;58 enum state state;
72};59};
7360
61static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
62 unsigned int id,
63 ofono_gprs_context_cb_t cb, void *data);
64
65static void set_context_disconnected(struct gprs_context_data *gcd)
66{
67 DBG("");
68
69 gcd->active_ctx_cid = -1;
70 gcd->active_rild_cid = -1;
71 gcd->state = STATE_IDLE;
72}
73
74static void disconnect_context(struct ofono_gprs_context *gc)
75{
76 ril_gprs_context_deactivate_primary(gc, 0, NULL, NULL);
77}
78
74static void ril_gprs_context_call_list_changed(struct ril_msg *message,79static void ril_gprs_context_call_list_changed(struct ril_msg *message,
75 gpointer user_data)80 gpointer user_data)
76{81{
77 struct ofono_gprs_context *gc = user_data;82 struct ofono_gprs_context *gc = user_data;
78 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);83 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
79 struct data_call *call = NULL;84 struct data_call *call = NULL;
85 struct unsol_data_call_list *unsol;
80 gboolean active_cid_found = FALSE;86 gboolean active_cid_found = FALSE;
81 gboolean disconnect = FALSE;87 gboolean disconnect = FALSE;
82 GSList *calls = NULL, *iterator = NULL;88 GSList *iterator = NULL;
89 struct ofono_error error;
8390
84 DBG("");91 DBG("");
8592
86 if (message->req != RIL_UNSOL_DATA_CALL_LIST_CHANGED) {93 unsol = g_ril_unsol_parse_data_call_list(gcd->ril, message, &error);
87 ofono_error("ril_gprs_update_calls: invalid message received %d",94
88 message->req);95 if (error.type != OFONO_ERROR_TYPE_NO_ERROR)
89 return;96 goto error;
90 }97
9198 DBG("number of call in call_list_changed is: %d", unsol->num);
92 calls = ril_util_parse_data_call_list(gcd->ril, message);99
93100 for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
94 DBG("number of call in call_list_changed is: %d", g_slist_length(calls));
95
96 for (iterator = calls; iterator; iterator = iterator->next) {
97 call = (struct data_call *) iterator->data;101 call = (struct data_call *) iterator->data;
98102
99 if (call->cid == gcd->active_rild_cid) {103 if (call->cid == gcd->active_rild_cid) {
@@ -113,13 +117,11 @@
113 if (disconnect || active_cid_found == FALSE) {117 if (disconnect || active_cid_found == FALSE) {
114 DBG("Clearing active context");118 DBG("Clearing active context");
115119
116 gcd->active_ctx_cid = -1;120 set_context_disconnected(gcd);
117 gcd->active_rild_cid = -1;
118 gcd->state = STATE_IDLE;
119 }121 }
120122
121 g_slist_foreach(calls, (GFunc) g_free, NULL);123error:
122 g_slist_free(calls);124 g_ril_unsol_free_data_call_list(unsol);
123}125}
124126
125static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)127static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
@@ -129,87 +131,67 @@
129 struct ofono_gprs_context *gc = cbd->user;131 struct ofono_gprs_context *gc = cbd->user;
130 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);132 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
131 struct ofono_error error;133 struct ofono_error error;
132 struct parcel rilp;134 struct reply_setup_data_call *reply;
133 int status, retry_time, cid, active, num, version;135 char **split_ip_addr = NULL;
134 char *dnses = NULL, *ifname = NULL;
135 char *raw_ip_addrs = NULL, *raw_gws = NULL, *type = NULL;
136 char **dns_addresses = NULL, **gateways = NULL;
137 char **ip_addrs = NULL, **split_ip_addr = NULL;
138
139 /* TODO:
140 * Cleanup duplicate code between this function and
141 * ril_util_parse_data_call_list().
142 */
143
144 /* valid size: 36 (34 if HCRADIO defined) */
145 if (message->buf_len < 36) {
146 DBG("Parcel is less then minimum DataCallResponseV6 size!");
147 decode_ril_error(&error, "FAIL");
148 goto error;
149 }
150136
151 if (message->error != RIL_E_SUCCESS) {137 if (message->error != RIL_E_SUCCESS) {
152 DBG("Reply failure: %s", ril_error_to_string(message->error));138 DBG("Reply failure: %s", ril_error_to_string(message->error));
153 decode_ril_error(&error, "FAIL");139
140 error.type = OFONO_ERROR_TYPE_FAILURE;
154 error.error = message->error;141 error.error = message->error;
155 goto error;142
156 }143 set_context_disconnected(gcd);
157144 goto error;
158 ril_util_init_parcel(message, &rilp);145 }
146
147 reply = g_ril_reply_parse_data_call(gcd->ril, message, &error);
148
149 gcd->active_rild_cid = reply->cid;
150
151 if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
152 if (gcd->active_rild_cid != -1)
153 disconnect_context(gc);
154
155 goto error;
156 }
157
158 if (reply->status != 0) {
159 ofono_error("%s: reply->status is non-zero: %d",
160 __func__,
161 reply->status);
162
163 error.type = OFONO_ERROR_TYPE_FAILURE;
164 error.error = reply->status;
165
166 set_context_disconnected(gcd);
167 goto error;
168 }
159169
160 /*170 /*
161 * ril.h documents the reply to a RIL_REQUEST_SETUP_DATA_CALL171 * TODO: consier moving this into parse_data_reply
162 * as being a RIL_Data_Call_Response_v6 struct, however in
163 * reality, the response actually includes the version of the
164 * struct, followed by an array of calls, so the array size
165 * also has to be read after the version.
166 *172 *
167 * TODO: What if there's more than 1 call in the list??173 * Note - the address may optionally include a prefix size
174 * ( Eg. "/30" ). As this confuses NetworkManager, we
175 * explicitly strip any prefix after calculating the netmask.
168 */176 */
169 version = parcel_r_int32(&rilp);177 split_ip_addr = g_strsplit(reply->ip_addrs[0], "/", 2);
170 num = parcel_r_int32(&rilp);178
171179 /* TODO: see note above re: invalid messages... */
172 status = parcel_r_int32(&rilp);180 if (split_ip_addr[0] == NULL) {
173 retry_time = parcel_r_int32(&rilp);181 ofono_error("%s: invalid IP address field returned: %s",
174 cid = parcel_r_int32(&rilp);182 __func__,
175 active = parcel_r_int32(&rilp);183 reply->ip_addrs[0]);
176184
177 type = parcel_r_string(&rilp);185 error.type = OFONO_ERROR_TYPE_FAILURE;
178 ifname = parcel_r_string(&rilp);186 error.error = EINVAL;
179 raw_ip_addrs = parcel_r_string(&rilp);187
180 dnses = parcel_r_string(&rilp);188 set_context_disconnected(gcd);
181 raw_gws = parcel_r_string(&rilp);
182
183 g_ril_append_print_buf(gcd->ril,
184 "{version=%d,num=%d [status=%d,retry=%d,cid=%d,active=%d,type=%s,ifname=%s,address=%s,dns=%s,gateways=%s]}",
185 version,
186 num,
187 status,
188 retry_time,
189 cid,
190 active,
191 type,
192 ifname,
193 raw_ip_addrs,
194 dnses,
195 raw_gws);
196 g_ril_print_response(gcd->ril, message);
197
198 if (status != 0) {
199 DBG("Reply failure; status %d", status);
200 gcd->state = STATE_IDLE;
201 goto error;189 goto error;
202 }190 }
203191
204 gcd->state = STATE_ACTIVE;192 gcd->state = STATE_ACTIVE;
205 gcd->active_rild_cid = cid;193
206194 ofono_gprs_context_set_interface(gc, reply->ifname);
207 ofono_gprs_context_set_interface(gc, ifname);
208
209 /*
210 * TODO: re-factor the following code into a
211 * ril_util function that can be unit-tested.
212 */
213195
214 /* TODO:196 /* TODO:
215 * RILD can return multiple addresses; oFono only supports197 * RILD can return multiple addresses; oFono only supports
@@ -218,65 +200,19 @@
218 * just specify the end-points of the point-to-point200 * just specify the end-points of the point-to-point
219 * connection, in which case this code will need to201 * connection, in which case this code will need to
220 * changed to handle such a device.202 * changed to handle such a device.
221 *
222 * For now split into a maximum of three, and only use
223 * the first address for the remaining operations.
224 */203 */
225 ip_addrs = g_strsplit(raw_ip_addrs, " ", 3);
226 if (ip_addrs[0] == NULL) {
227 DBG("No IP address specified: %s", raw_ip_addrs);
228 decode_ril_error(&error, "FAIL");
229 goto error;
230 }
231
232 ofono_gprs_context_set_ipv4_netmask(gc,204 ofono_gprs_context_set_ipv4_netmask(gc,
233 ril_util_get_netmask(ip_addrs[0]));205 ril_util_get_netmask(reply->ip_addrs[0]));
234
235 /*
236 * Note - the address may optionally include a prefix size
237 * ( Eg. "/30" ). As this confuses NetworkManager, we
238 * explicitly strip any prefix after calculating the netmask.
239 */
240 split_ip_addr = g_strsplit(ip_addrs[0], "/", 2);
241 if (split_ip_addr[0] == NULL) {
242 DBG("Invalid IP address field returned: %s", raw_ip_addrs);
243 decode_ril_error(&error, "FAIL");
244 goto error;
245 }
246206
247 ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);207 ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
248208 ofono_gprs_context_set_ipv4_gateway(gc, reply->gateways[0]);
249 /*209
250 * RILD can return multiple addresses; oFono only supports
251 * setting a single IPv4 gateway.
252 */
253 gateways = g_strsplit(raw_gws, " ", 3);
254 if (gateways[0] == NULL) {
255 DBG("Invalid gateways field returned: %s", raw_gws);
256 decode_ril_error(&error, "FAIL");
257 goto error;
258 }
259
260 ofono_gprs_context_set_ipv4_gateway(gc, gateways[0]);
261
262 /* Split DNS addresses */
263 dns_addresses = g_strsplit(dnses, " ", 3);
264 ofono_gprs_context_set_ipv4_dns_servers(gc,210 ofono_gprs_context_set_ipv4_dns_servers(gc,
265 (const char **) dns_addresses);211 (const char **) reply->dns_addresses);
266
267 decode_ril_error(&error, "OK");
268212
269error:213error:
270 g_strfreev(dns_addresses);214 g_ril_reply_free_setup_data_call(reply);
271 g_strfreev(ip_addrs);
272 g_strfreev(split_ip_addr);215 g_strfreev(split_ip_addr);
273 g_strfreev(gateways);
274
275 g_free(type);
276 g_free(ifname);
277 g_free(raw_ip_addrs);
278 g_free(dnses);
279 g_free(raw_gws);
280216
281 cb(&error, cbd->data);217 cb(&error, cbd->data);
282}218}
@@ -287,91 +223,61 @@
287{223{
288 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);224 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
289 struct cb_data *cbd = cb_data_new(cb, data);225 struct cb_data *cbd = cb_data_new(cb, data);
226 struct req_setup_data_call request;
290 struct parcel rilp;227 struct parcel rilp;
291 gchar *protocol = PROTO_IP;228 struct ofono_error error;
292 gchar tech[3];229 int reqid = RIL_REQUEST_SETUP_DATA_CALL;
293 int request = RIL_REQUEST_SETUP_DATA_CALL;230 int ret = 0;
294 int ret;231
232 DBG("Activating contex: %d", ctx->cid);
295233
296 cbd->user = gc;234 cbd->user = gc;
235
236 /* TODO: implement radio technology selection. */
237 request.tech = RADIO_TECH_HSPA;
238
239 /* TODO: add comments about tethering, other non-public
240 * profiles...
241 */
242 request.data_profile = RIL_DATA_PROFILE_DEFAULT;
243 request.apn = g_strdup(ctx->apn);
244 request.username = g_strdup(ctx->username);
245 request.password = g_strdup(ctx->password);
246 request.auth_type = RIL_AUTH_BOTH;
247 request.protocol = ctx->proto;
248
249 if (g_ril_request_setup_data_call(gcd->ril,
250 &request,
251 &rilp,
252 &error) == FALSE) {
253 ofono_error("Couldn't build SETUP_DATA_CALL request.");
254 goto error;
255 }
256
297 gcd->active_ctx_cid = ctx->cid;257 gcd->active_ctx_cid = ctx->cid;
298 gcd->state = STATE_ENABLING;258 gcd->state = STATE_ENABLING;
299259
300 memcpy(gcd->username, ctx->username, sizeof(ctx->username));
301 memcpy(gcd->password, ctx->password, sizeof(ctx->password));
302
303 parcel_init(&rilp);
304 parcel_w_int32(&rilp, SETUP_DATA_CALL_PARAMS);
305
306 /* RadioTech: hardcoded to HSPA for now... */
307 sprintf((char *) tech, "%d", (int) RADIO_TECH_HSPA);
308 DBG("setting tech to: %s", tech);
309 parcel_w_string(&rilp, (char *) tech);
310
311 /*
312 * TODO ( OEM/Tethering ): DataProfile:
313 *
314 * Other options are TETHERING (1) or OEM_BASE (1000).
315 */
316 parcel_w_string(&rilp, DATA_PROFILE_DEFAULT);
317
318 /* APN */
319 parcel_w_string(&rilp, (char *) (ctx->apn));
320
321 if (ctx->username && strlen(ctx->username)) {
322 parcel_w_string(&rilp, (char *) (ctx->username));
323 } else {
324 parcel_w_string(&rilp, NULL);
325 }
326
327 if (ctx->password && strlen(ctx->password)) {
328 parcel_w_string(&rilp, (char *) (ctx->password));
329 } else {
330 parcel_w_string(&rilp, NULL);
331 }
332
333 /*
334 * TODO: review with operators...
335 * Auth type: PAP/CHAP may be performed
336 */
337 parcel_w_string(&rilp, CHAP_PAP_OK);
338
339 switch (ctx->proto) {
340 case OFONO_GPRS_PROTO_IPV6:
341 protocol = PROTO_IPV6;
342 break;
343 case OFONO_GPRS_PROTO_IPV4V6:
344 protocol = PROTO_IPV4V6;
345 break;
346 case OFONO_GPRS_PROTO_IP:
347 break;
348 default:
349 DBG("Invalid protocol: %d", ctx->proto);
350 }
351
352 parcel_w_string(&rilp, protocol);
353
354 ret = g_ril_send(gcd->ril,260 ret = g_ril_send(gcd->ril,
355 request,261 reqid,
356 rilp.data,262 rilp.data,
357 rilp.size,263 rilp.size,
358 ril_setup_data_call_cb, cbd, g_free);264 ril_setup_data_call_cb, cbd, g_free);
359265
360 g_ril_append_print_buf(gcd->ril,266 /* NOTE - we could make the following function part of g_ril_send? */
361 "(%s,%s,%s,%s,%s,%s,%s)",267 g_ril_print_request(gcd->ril, ret, reqid);
362 tech,
363 DATA_PROFILE_DEFAULT,
364 ctx->apn,
365 ctx->username,
366 ctx->password,
367 CHAP_PAP_OK,
368 protocol);
369 g_ril_print_request(gcd->ril, ret, request);
370268
371 parcel_free(&rilp);269 parcel_free(&rilp);
270
271error:
272 g_free(request.apn);
273 g_free(request.username);
274 g_free(request.password);
275
372 if (ret <= 0) {276 if (ret <= 0) {
373 ofono_error("Send RIL_REQUEST_SETUP_DATA_CALL failed.");277 ofono_error("Send RIL_REQUEST_SETUP_DATA_CALL failed.");
374278
279 set_context_disconnected(gcd);
280
375 g_free(cbd);281 g_free(cbd);
376 CALLBACK_WITH_FAILURE(cb, data);282 CALLBACK_WITH_FAILURE(cb, data);
377 }283 }
@@ -383,7 +289,6 @@
383 ofono_gprs_context_cb_t cb = cbd->cb;289 ofono_gprs_context_cb_t cb = cbd->cb;
384 struct ofono_gprs_context *gc = cbd->user;290 struct ofono_gprs_context *gc = cbd->user;
385 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);291 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
386 struct ofono_error error;
387292
388 DBG("");293 DBG("");
389294
@@ -392,16 +297,24 @@
392297
393 g_ril_print_response_no_args(gcd->ril, message);298 g_ril_print_response_no_args(gcd->ril, message);
394299
395 gcd->state = STATE_IDLE;300 set_context_disconnected(gcd);
396 CALLBACK_WITH_SUCCESS(cb, cbd->data);301
302 /* If the deactivate was a result of a shutdown,
303 * there won't be call back, so _deactivated()
304 * needs to be called directly.
305 */
306 if (cb)
307 CALLBACK_WITH_SUCCESS(cb, cbd->data);
308 else
309 ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
397310
398 } else {311 } else {
399 DBG("Reply failure: %s", ril_error_to_string(message->error));312 ofono_error("%s: replay failure: %s",
400313 __func__,
401 decode_ril_error(&error, "FAIL");314 ril_error_to_string(message->error));
402 error.error = message->error;315
403316 if (cb)
404 cb(&error, cbd->data);317 CALLBACK_WITH_FAILURE(cb, cbd->data);
405 }318 }
406}319}
407320
@@ -410,51 +323,67 @@
410 ofono_gprs_context_cb_t cb, void *data)323 ofono_gprs_context_cb_t cb, void *data)
411{324{
412 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);325 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
413 struct cb_data *cbd = cb_data_new(cb, data);326 struct cb_data *cbd = NULL;
414 struct parcel rilp;327 struct parcel rilp;
415 gchar *cid = NULL;328 struct req_deactivate_data_call request;
416 int request = RIL_REQUEST_DEACTIVATE_DATA_CALL;329 struct ofono_error error;
417 int ret;330 int reqid = RIL_REQUEST_DEACTIVATE_DATA_CALL;
418331 int ret = 0;
332
333 DBG("");
334
335 if (gcd->active_rild_cid == -1) {
336 set_context_disconnected(gcd);
337
338 if (cb) {
339 CALLBACK_WITH_SUCCESS(cb, data);
340 g_free(cbd);
341 }
342
343 return;
344 }
345
346
347 cbd = cb_data_new(cb, data);
419 cbd->user = gc;348 cbd->user = gc;
420349
421 gcd->state = STATE_DISABLING;350 gcd->state = STATE_DISABLING;
422351
423 parcel_init(&rilp);352 request.cid = gcd->active_rild_cid;
424 parcel_w_int32(&rilp, DEACTIVATE_DATA_CALL_NUM_PARAMS);353 request.reason = RIL_DEACTIVATE_DATA_CALL_NO_REASON;
425354
426 cid = g_strdup_printf("%d", gcd->active_rild_cid);355 if (g_ril_request_deactivate_data_call(gcd->ril, &request,
427 parcel_w_string(&rilp, cid);356 &rilp, &error) == FALSE) {
428357 ofono_error("Couldn't build DEACTIVATE_DATA_CALL request.");
429 /*358 goto error;
430 * TODO: airplane-mode; change reason to '1',359 }
431 * which means "radio power off".
432 */
433 parcel_w_string(&rilp, DEACTIVATE_DATA_CALL_NO_REASON);
434360
435 ret = g_ril_send(gcd->ril,361 ret = g_ril_send(gcd->ril,
436 request,362 reqid,
437 rilp.data,363 rilp.data,
438 rilp.size,364 rilp.size,
439 ril_deactivate_data_call_cb, cbd, g_free);365 ril_deactivate_data_call_cb, cbd, g_free);
440366
441 g_ril_append_print_buf(gcd->ril, "(%s,0)", cid);367 g_ril_append_print_buf(gcd->ril, "(%d,0)", request.cid);
442 g_ril_print_request(gcd->ril, ret, request);368 g_ril_print_request(gcd->ril, ret, reqid);
443369
444 parcel_free(&rilp);370 parcel_free(&rilp);
445 g_free(cid);
446371
372error:
447 if (ret <= 0) {373 if (ret <= 0) {
448 ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");374 ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");
449 g_free(cbd);375 g_free(cbd);
450 CALLBACK_WITH_FAILURE(cb, data);376 if (cb)
377 CALLBACK_WITH_FAILURE(cb, data);
451 }378 }
452}379}
453380
454static void ril_gprs_context_detach_shutdown(struct ofono_gprs_context *gc,381static void ril_gprs_context_detach_shutdown(struct ofono_gprs_context *gc,
455 unsigned int id)382 unsigned int id)
456{383{
457 DBG("");384 DBG("cid: %d", id);
385
386 ril_gprs_context_deactivate_primary(gc, 0, NULL, NULL);
458}387}
459388
460static int ril_gprs_context_probe(struct ofono_gprs_context *gc,389static int ril_gprs_context_probe(struct ofono_gprs_context *gc,
@@ -468,9 +397,7 @@
468 return -ENOMEM;397 return -ENOMEM;
469398
470 gcd->ril = g_ril_clone(ril);399 gcd->ril = g_ril_clone(ril);
471 gcd->active_ctx_cid = -1;400 set_context_disconnected(gcd);
472 gcd->active_rild_cid = -1;
473 gcd->state = STATE_IDLE;
474401
475 ofono_gprs_context_set_data(gc, gcd);402 ofono_gprs_context_set_data(gc, gcd);
476403
@@ -486,7 +413,7 @@
486 DBG("");413 DBG("");
487414
488 if (gcd->state != STATE_IDLE) {415 if (gcd->state != STATE_IDLE) {
489 /* TODO: call detach_shutdown */416 ril_gprs_context_detach_shutdown(gc, 0);
490 }417 }
491418
492 ofono_gprs_context_set_data(gc, NULL);419 ofono_gprs_context_set_data(gc, NULL);
493420
=== modified file 'drivers/rilmodem/rilutil.c'
--- drivers/rilmodem/rilutil.c 2013-07-08 18:02:27 +0000
+++ drivers/rilmodem/rilutil.c 2013-07-28 19:18:23 +0000
@@ -97,20 +97,6 @@
97 return 0;97 return 0;
98}98}
9999
100gint ril_util_data_call_compare(gconstpointer a, gconstpointer b)
101{
102 const struct data_call *ca = a;
103 const struct data_call *cb = b;
104
105 if (ca->cid < cb->cid)
106 return -1;
107
108 if (ca->cid > cb->cid)
109 return 1;
110
111 return 0;
112}
113
114gint ril_util_call_compare(gconstpointer a, gconstpointer b)100gint ril_util_call_compare(gconstpointer a, gconstpointer b)
115{101{
116 const struct ofono_call *ca = a;102 const struct ofono_call *ca = a;
@@ -171,6 +157,8 @@
171 return result;157 return result;
172}158}
173159
160/* TODO: this function can go away, once all the code has been
161 * re-factored to use grilreply.c */
174void ril_util_init_parcel(struct ril_msg *message, struct parcel *rilp)162void ril_util_init_parcel(struct ril_msg *message, struct parcel *rilp)
175{163{
176 /* Set up Parcel struct for proper parsing */164 /* Set up Parcel struct for proper parsing */
@@ -283,73 +271,6 @@
283 return l;271 return l;
284}272}
285273
286GSList *ril_util_parse_data_call_list(GRil *gril, struct ril_msg *message)
287{
288 struct data_call *call;
289 struct parcel rilp;
290 GSList *l = NULL;
291 int num, i, version;
292 gchar *number, *name;
293
294 ril_util_init_parcel(message, &rilp);
295
296 /*
297 * ril.h documents the reply to a RIL_REQUEST_DATA_CALL_LIST
298 * as being an array of RIL_Data_Call_Response_v6 structs,
299 * however in reality, the response also includes a version
300 * to start.
301 */
302 version = parcel_r_int32(&rilp);
303
304 /* Number of calls */
305 num = parcel_r_int32(&rilp);
306
307 g_ril_append_print_buf(gril,
308 "(version=%d,num=%d",
309 version,
310 num);
311
312 for (i = 0; i < num; i++) {
313 call = g_try_new(struct data_call, 1);
314 if (call == NULL)
315 break;
316
317 call->status = parcel_r_int32(&rilp);
318 call->retry = parcel_r_int32(&rilp);
319 call->cid = parcel_r_int32(&rilp);
320 call->active = parcel_r_int32(&rilp);
321
322 call->type = parcel_r_string(&rilp);
323 call->ifname = parcel_r_string(&rilp);
324 call->addresses = parcel_r_string(&rilp);
325 call->dnses = parcel_r_string(&rilp);
326 call->gateways = parcel_r_string(&rilp);
327
328 /* TODO: figure out how to line-wrap properly
329 * without introducing spaces in string.
330 */
331 g_ril_append_print_buf(gril,
332 "%s [status=%d,retry=%d,cid=%d,active=%d,type=%s,ifname=%s,address=%s,dns=%s,gateways=%s]",
333 print_buf,
334 call->status,
335 call->retry,
336 call->cid,
337 call->active,
338 call->type,
339 call->ifname,
340 call->addresses,
341 call->dnses,
342 call->gateways);
343
344 l = g_slist_insert_sorted(l, call, ril_util_data_call_compare);
345 }
346
347 g_ril_append_print_buf(gril, "%s}", print_buf);
348 g_ril_print_response(gril, message);
349
350 return l;
351}
352
353char *ril_util_parse_sim_io_rsp(GRil *gril,274char *ril_util_parse_sim_io_rsp(GRil *gril,
354 struct ril_msg *message,275 struct ril_msg *message,
355 int *sw1, int *sw2,276 int *sw1, int *sw2,
356277
=== modified file 'drivers/rilmodem/rilutil.h'
--- drivers/rilmodem/rilutil.h 2013-07-08 17:17:54 +0000
+++ drivers/rilmodem/rilutil.h 2013-07-28 19:18:23 +0000
@@ -72,18 +72,6 @@
72 APPSTATE_READY,72 APPSTATE_READY,
73};73};
7474
75struct data_call {
76 int status;
77 int retry;
78 int cid;
79 int active;
80 char *type;
81 char *ifname;
82 char *addresses;
83 char *dnses;
84 char *gateways;
85};
86
87#define MAX_UICC_APPS 1675#define MAX_UICC_APPS 16
8876
89struct sim_status {77struct sim_status {
@@ -124,7 +112,6 @@
124void ril_util_sim_state_query_free(struct ril_util_sim_state_query *req);112void ril_util_sim_state_query_free(struct ril_util_sim_state_query *req);
125113
126GSList *ril_util_parse_clcc(GRil *gril, struct ril_msg *message);114GSList *ril_util_parse_clcc(GRil *gril, struct ril_msg *message);
127GSList *ril_util_parse_data_call_list(GRil *gril, struct ril_msg *message);
128char *ril_util_parse_sim_io_rsp(GRil *gril, struct ril_msg *message,115char *ril_util_parse_sim_io_rsp(GRil *gril, struct ril_msg *message,
129 int *sw1, int *sw2,116 int *sw1, int *sw2,
130 int *hex_len);117 int *hex_len);
131118
=== modified file 'gril/gril.c'
--- gril/gril.c 2013-06-25 16:15:35 +0000
+++ gril/gril.c 2013-07-28 19:18:23 +0000
@@ -40,6 +40,7 @@
40#include "log.h"40#include "log.h"
41#include "ringbuffer.h"41#include "ringbuffer.h"
42#include "gril.h"42#include "gril.h"
43#include "grilutil.h"
4344
44#define RIL_TRACE(ril, fmt, arg...) do { \45#define RIL_TRACE(ril, fmt, arg...) do { \
45 if (ril->trace == TRUE) \46 if (ril->trace == TRUE) \
@@ -119,6 +120,9 @@
119 guint32 error_code; /* LE: */120 guint32 error_code; /* LE: */
120};121};
121122
123#define RIL_PRINT_BUF_SIZE 8096
124char print_buf[RIL_PRINT_BUF_SIZE] __attribute__((used));
125
122static void ril_wakeup_writer(struct ril_s *ril);126static void ril_wakeup_writer(struct ril_s *ril);
123127
124static void ril_notify_node_destroy(gpointer data, gpointer user_data)128static void ril_notify_node_destroy(gpointer data, gpointer user_data)
@@ -240,7 +244,7 @@
240244
241245
242 DBG("req: %s, id: %d, data_len: %d",246 DBG("req: %s, id: %d, data_len: %d",
243 ril_request_id_to_string(req), id, data_len);247 ril_request_id_to_string(req), id, (int) data_len);
244248
245 /* RIL request: 8 byte header + data */249 /* RIL request: 8 byte header + data */
246 len = 8 + data_len;250 len = 8 + data_len;
@@ -634,7 +638,9 @@
634638
635 len = req->data_len;639 len = req->data_len;
636640
637 DBG("len: %d, req_bytes_written: %d", len, ril->req_bytes_written);641 DBG("len: %d, req_bytes_written: %d",
642 (int) len,
643 ril->req_bytes_written);
638644
639 /* For some reason write watcher fired, but we've already645 /* For some reason write watcher fired, but we've already
640 * written the entire command out to the io channel,646 * written the entire command out to the io channel,
@@ -810,8 +816,6 @@
810 return NULL;816 return NULL;
811 }817 }
812818
813 g_io_channel_set_buffered(io, FALSE);
814 g_io_channel_set_encoding(io, NULL, NULL);
815 g_io_channel_set_close_on_unref(io, TRUE);819 g_io_channel_set_close_on_unref(io, TRUE);
816 g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);820 g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
817821
@@ -956,6 +960,15 @@
956 return FALSE;960 return FALSE;
957}961}
958962
963void g_ril_init_parcel(struct ril_msg *message, struct parcel *rilp)
964{
965 /* Set up Parcel struct for proper parsing */
966 rilp->data = message->buf;
967 rilp->size = message->buf_len;
968 rilp->capacity = message->buf_len;
969 rilp->offset = 0;
970}
971
959GRil *g_ril_new()972GRil *g_ril_new()
960{973{
961 GRil *ril;974 GRil *ril;
@@ -1022,7 +1035,7 @@
1022 return ril;1035 return ril;
1023}1036}
10241037
1025guint g_ril_send(GRil *ril, const guint req, const char *data,1038guint g_ril_send(GRil *ril, const guint reqid, const char *data,
1026 const gsize data_len, GRilResponseFunc func,1039 const gsize data_len, GRilResponseFunc func,
1027 gpointer user_data, GDestroyNotify notify)1040 gpointer user_data, GDestroyNotify notify)
1028{1041{
@@ -1034,7 +1047,7 @@
10341047
1035 p = ril->parent;1048 p = ril->parent;
10361049
1037 r = ril_request_create(p, ril->group, req, p->next_cmd_id,1050 r = ril_request_create(p, ril->group, reqid, p->next_cmd_id,
1038 data, data_len, func,1051 data, data_len, func,
1039 user_data, notify, FALSE);1052 user_data, notify, FALSE);
1040 if (r == NULL)1053 if (r == NULL)
10411054
=== modified file 'gril/gril.h'
--- gril/gril.h 2013-06-14 16:11:01 +0000
+++ gril/gril.h 2013-07-28 19:18:23 +0000
@@ -27,9 +27,9 @@
27extern "C" {27extern "C" {
28#endif28#endif
2929
30#include "grilresponse.h"30#include "grilio.h"
31#include "grilutil.h"31#include "grilutil.h"
32#include "grilio.h"32#include "parcel.h"
33#include "ril_constants.h"33#include "ril_constants.h"
3434
35struct _GRil;35struct _GRil;
@@ -63,12 +63,11 @@
63 * name it is called in.63 * name it is called in.
64 */64 */
65#define G_RIL_TRACE(gril, fmt, arg...) do { \65#define G_RIL_TRACE(gril, fmt, arg...) do { \
66 if (g_ril_get_trace(gril)) \66 if (gril && g_ril_get_trace(gril)) \
67 ofono_debug(fmt, ## arg); \67 ofono_debug(fmt, ## arg); \
68} while (0)68} while (0)
6969
70#define RIL_PRINT_BUF_SIZE 809670extern char print_buf[];
71static char print_buf[RIL_PRINT_BUF_SIZE] __attribute__((used));
7271
73#define g_ril_print_request(gril, token, req) \72#define g_ril_print_request(gril, token, req) \
74 G_RIL_TRACE(gril, "[%04d]> %s %s", token, ril_request_id_to_string(req), print_buf)73 G_RIL_TRACE(gril, "[%04d]> %s %s", token, ril_request_id_to_string(req), print_buf)
@@ -82,7 +81,7 @@
82 ril_request_id_to_string(message->req))81 ril_request_id_to_string(message->req))
8382
84#define g_ril_append_print_buf(gril, x...) do { \83#define g_ril_append_print_buf(gril, x...) do { \
85 if (g_ril_get_trace(gril)) \84 if (gril && g_ril_get_trace(gril)) \
86 sprintf(print_buf, x); \85 sprintf(print_buf, x); \
87} while (0)86} while (0)
8887
@@ -92,6 +91,8 @@
92#define g_ril_print_unsol_no_args(gril, message) \91#define g_ril_print_unsol_no_args(gril, message) \
93 G_RIL_TRACE(gril, "[UNSOL]< %s", ril_unsol_request_to_string(message->req))92 G_RIL_TRACE(gril, "[UNSOL]< %s", ril_unsol_request_to_string(message->req))
9493
94void g_ril_init_parcel(struct ril_msg *message, struct parcel *rilp);
95
95GRil *g_ril_new();96GRil *g_ril_new();
9697
97GIOChannel *g_ril_get_channel(GRil *ril);98GIOChannel *g_ril_get_channel(GRil *ril);
@@ -127,8 +128,9 @@
127 * g_ril_cancel. If an error occurred, an id of 0 is returned.128 * g_ril_cancel. If an error occurred, an id of 0 is returned.
128 *129 *
129 */130 */
130guint g_ril_send(GRil *ril, const guint req, const char *data, const gsize data_len,131guint g_ril_send(GRil *ril, const guint reqid, const char *data,
131 GRilResponseFunc func, gpointer user_data, GDestroyNotify notify);132 const gsize data_len, GRilResponseFunc func,
133 gpointer user_data, GDestroyNotify notify);
132134
133guint g_ril_register(GRil *ril, const int req,135guint g_ril_register(GRil *ril, const int req,
134 GRilNotifyFunc func, gpointer user_data);136 GRilNotifyFunc func, gpointer user_data);
135137
=== added file 'gril/grilreply.c'
--- gril/grilreply.c 1970-01-01 00:00:00 +0000
+++ gril/grilreply.c 2013-07-28 19:18:23 +0000
@@ -0,0 +1,225 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012-2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdio.h>
28#include <ctype.h>
29#include <errno.h>
30#include <string.h>
31
32#include <glib.h>
33
34#include <ofono/log.h>
35#include <ofono/modem.h>
36#include <ofono/gprs-context.h>
37
38#include "grilreply.h"
39#include "grilutil.h"
40
41/* SETUP_DATA_CALL_PARAMS reply params */
42#define MIN_DATA_CALL_REPLY_SIZE 36
43
44/* TODO: move this to grilutil.c */
45void g_ril_reply_free_setup_data_call(struct reply_setup_data_call *reply)
46{
47 if (reply) {
48 g_free(reply->ifname);
49 g_strfreev(reply->dns_addresses);
50 g_strfreev(reply->gateways);
51 g_strfreev(reply->ip_addrs);
52 g_free(reply);
53 }
54}
55
56struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
57 struct ril_msg *message,
58 struct ofono_error *error)
59{
60 struct parcel rilp;
61 int num = 0;
62 int protocol;
63 char *type = NULL, *raw_ip_addrs = NULL;
64 char *dnses = NULL, *raw_gws = NULL;
65
66 struct reply_setup_data_call *reply =
67 g_new0(struct reply_setup_data_call, 1);
68
69 OFONO_NO_ERROR(error);
70
71 reply->cid = -1;
72
73 /* TODO:
74 * Cleanup duplicate code between this function and
75 * ril_util_parse_data_call_list().
76 */
77
78 /* valid size: 36 (34 if HCRADIO defined) */
79 if (message->buf_len < MIN_DATA_CALL_REPLY_SIZE) {
80 /* TODO: make a macro for error logging */
81 ofono_error("%s: reply too small: %d",
82 __func__,
83 (int) message->buf_len);
84 OFONO_EINVAL(error);
85 goto error;
86 }
87
88 g_ril_init_parcel(message, &rilp);
89
90 /*
91 * ril.h documents the reply to a RIL_REQUEST_SETUP_DATA_CALL
92 * as being a RIL_Data_Call_Response_v6 struct, however in
93 * reality, the response actually includes the version of the
94 * struct, followed by an array of calls, so the array size
95 * also has to be read after the version.
96 *
97 * TODO: What if there's more than 1 call in the list??
98 */
99
100 /*
101 * TODO: consider using 'unused' variable; however if we
102 * do this, the alternative is a few more append_print_buf
103 * calls ( which become no-ops if tracing isn't enabled.
104 */
105 reply->version = parcel_r_int32(&rilp);
106 num = parcel_r_int32(&rilp);
107 if (num != 1) {
108 ofono_error("%s: too many calls: %d", __func__, num);
109 OFONO_EINVAL(error);
110 goto error;
111 }
112
113 reply->status = parcel_r_int32(&rilp);
114 reply->retry_time = parcel_r_int32(&rilp);
115 reply->cid = parcel_r_int32(&rilp);
116 reply->active = parcel_r_int32(&rilp);
117 type = parcel_r_string(&rilp);
118 reply->ifname = parcel_r_string(&rilp);
119 raw_ip_addrs = parcel_r_string(&rilp);
120 dnses = parcel_r_string(&rilp);
121 raw_gws = parcel_r_string(&rilp);
122
123 g_ril_append_print_buf(gril,
124 "{version=%d,num=%d [status=%d,retry=%d,"
125 "cid=%d,active=%d,type=%s,ifname=%s,address=%s"
126 ",dns=%s,gateways=%s]}",
127 reply->version,
128 num,
129 reply->status,
130 reply->retry_time,
131 reply->cid,
132 reply->active,
133 type,
134 reply->ifname,
135 raw_ip_addrs,
136 dnses,
137 raw_gws);
138
139 g_ril_print_response(gril, message);
140
141 protocol = ril_protocol_string_to_ofono_protocol(type);
142 if (protocol < 0) {
143 ofono_error("%s: Invalid type(protocol) specified: %s",
144 __func__,
145 type);
146 OFONO_EINVAL(error);
147 goto error;
148 }
149
150 reply->protocol = (guint) protocol;
151
152 if (reply->ifname == NULL || strlen(reply->ifname) == 0) {
153 ofono_error("%s: No interface specified: %s",
154 __func__,
155 reply->ifname);
156
157 OFONO_EINVAL(error);
158 goto error;
159
160 }
161
162 /* TODO:
163 * RILD can return multiple addresses; oFono only supports
164 * setting a single IPv4 address. At this time, we only
165 * use the first address. It's possible that a RIL may
166 * just specify the end-points of the point-to-point
167 * connection, in which case this code will need to
168 * changed to handle such a device.
169 *
170 * For now split into a maximum of three, and only use
171 * the first address for the remaining operations.
172 */
173 if (raw_ip_addrs)
174 reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", 3);
175 else
176 reply->ip_addrs = NULL;
177
178 /* TODO: I'm not sure it's possible to specify a zero-length
179 * in a parcel in a parcel. If *not*, then this can be
180 * simplified.
181 */
182 if (reply->ip_addrs == NULL || (sizeof(reply->ip_addrs) == 0)) {
183 ofono_error("%s no IP address: %s", __func__, raw_ip_addrs);
184
185 OFONO_EINVAL(error);
186 goto error;
187 }
188
189 /*
190 * RILD can return multiple addresses; oFono only supports
191 * setting a single IPv4 gateway.
192 */
193 if (raw_gws)
194 reply->gateways = g_strsplit(raw_gws, " ", 3);
195 else
196 reply->gateways = NULL;
197
198 if (reply->gateways == NULL || (sizeof(reply->gateways) == 0)) {
199 ofono_error("%s: no gateways: %s", __func__, raw_gws);
200 OFONO_EINVAL(error);
201 goto error;
202 }
203
204 /* Split DNS addresses */
205 if (dnses)
206 reply->dns_addresses = g_strsplit(dnses, " ", 3);
207 else
208 reply->dns_addresses = NULL;
209
210 if (reply->dns_addresses == NULL ||
211 (sizeof(reply->dns_addresses) == 0)) {
212 ofono_error("%s: no DNS: %s", __func__, dnses);
213
214 OFONO_EINVAL(error);
215 goto error;
216 }
217
218error:
219 g_free(type);
220 g_free(raw_ip_addrs);
221 g_free(dnses);
222 g_free(raw_gws);
223
224 return reply;
225}
0226
=== added file 'gril/grilreply.h'
--- gril/grilreply.h 1970-01-01 00:00:00 +0000
+++ gril/grilreply.h 2013-07-28 19:18:23 +0000
@@ -0,0 +1,57 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012-2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef __GRILREPLY_H
24#define __GRILREPLY_H
25
26#include <ofono/types.h>
27
28#include "gril.h"
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34struct reply_setup_data_call {
35 guint version;
36 guint status;
37 gint cid;
38 guint retry_time;
39 guint active;
40 guint protocol;
41 gchar *ifname;
42 gchar **dns_addresses;
43 gchar **gateways;
44 gchar **ip_addrs;
45};
46
47void g_ril_reply_free_setup_data_call(struct reply_setup_data_call *reply);
48
49struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
50 struct ril_msg *message,
51 struct ofono_error *error);
52
53#ifdef __cplusplus
54}
55#endif
56
57#endif /* __GRILREPLY_H */
058
=== added file 'gril/grilrequest.c'
--- gril/grilrequest.c 1970-01-01 00:00:00 +0000
+++ gril/grilrequest.c 2013-07-28 19:18:23 +0000
@@ -0,0 +1,213 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012-2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdio.h>
28#include <ctype.h>
29#include <errno.h>
30#include <string.h>
31
32#include <glib.h>
33
34#include <ofono/log.h>
35#include <ofono/modem.h>
36#include <ofono/gprs-context.h>
37
38#include "grilrequest.h"
39
40/* DEACTIVATE_DATA_CALL request parameters */
41#define DEACTIVATE_DATA_CALL_NUM_PARAMS 2
42
43/* SETUP_DATA_CALL_PARAMS request parameters */
44#define SETUP_DATA_CALL_PARAMS 7
45#define DATA_PROFILE_DEFAULT_STR "0"
46#define DATA_PROFILE_TETHERED_STR "1"
47#define DATA_PROFILE_IMS_STR "2"
48#define DATA_PROFILE_FOTA_STR "3"
49#define DATA_PROFILE_CBS_STR "4"
50#define DATA_PROFILE_OEM_BASE_STR "1000"
51
52/* SETUP_DATA_CALL_PARAMS reply parameters */
53#define MIN_DATA_CALL_REPLY_SIZE 36
54
55/*
56 * TODO:
57 *
58 * A potential future change here is to create a driver
59 * abstraction for each request/reply/event method, and a
60 * corresponding method to allow new per-message implementations
61 * to be registered. This would allow PES to easily add code
62 * to quirk a particular RIL implementation.
63 *
64 * struct g_ril_messages_driver {
65 * const char *name;
66 * };
67 *
68 */
69
70gboolean g_ril_request_deactivate_data_call(GRil *gril,
71 const struct req_deactivate_data_call *req,
72 struct parcel *rilp,
73 struct ofono_error *error)
74{
75 gchar *cid_str = NULL;
76 gchar *reason_str = NULL;
77
78 if (req->reason != RIL_DEACTIVATE_DATA_CALL_NO_REASON &&
79 req->reason != RIL_DEACTIVATE_DATA_CALL_RADIO_SHUTDOWN) {
80 goto error;
81 }
82
83 parcel_init(rilp);
84 parcel_w_int32(rilp, DEACTIVATE_DATA_CALL_NUM_PARAMS);
85
86 cid_str = g_strdup_printf("%d", req->cid);
87 parcel_w_string(rilp, cid_str);
88
89 /*
90 * TODO: airplane-mode; change reason to '1',
91 * which means "radio power off".
92 */
93 reason_str = g_strdup_printf("%d", req->reason);
94 parcel_w_string(rilp, reason_str);
95
96 g_free(cid_str);
97 g_free(reason_str);
98
99 OFONO_NO_ERROR(error);
100 return TRUE;
101
102error:
103 OFONO_EINVAL(error);
104 return FALSE;
105}
106
107gboolean g_ril_request_setup_data_call(GRil *gril,
108 const struct req_setup_data_call *req,
109 struct parcel *rilp,
110 struct ofono_error *error)
111{
112 const gchar *protocol_str;
113 gchar *tech_str;
114 gchar *auth_str;
115 gchar *profile_str;
116 size_t apn_len;
117
118 DBG("");
119
120 if (req->tech < RADIO_TECH_GPRS || req->tech > RADIO_TECH_GSM) {
121 ofono_error("%s: Invalid tech value: %d", __func__, req->tech);
122 goto error;
123 }
124
125 /*
126 * TODO(OEM): This code doesn't currently support
127 * OEM data profiles. If a use case exist, then
128 * this code will need to be modified.
129 */
130 switch (req->data_profile) {
131 case RIL_DATA_PROFILE_DEFAULT:
132 profile_str = DATA_PROFILE_DEFAULT_STR;
133 break;
134 case RIL_DATA_PROFILE_TETHERED:
135 profile_str = DATA_PROFILE_TETHERED_STR;
136 break;
137 case RIL_DATA_PROFILE_IMS:
138 profile_str = DATA_PROFILE_IMS_STR;
139 break;
140 case RIL_DATA_PROFILE_FOTA:
141 profile_str = DATA_PROFILE_FOTA_STR;
142 break;
143 case RIL_DATA_PROFILE_CBS:
144 profile_str = DATA_PROFILE_CBS_STR;
145 break;
146 default:
147 ofono_error("%s, invalid data_profile value: %d",
148 __func__,
149 req->data_profile);
150 goto error;
151 }
152
153 if (req->apn == NULL)
154 goto error;
155
156 apn_len = strlen(req->apn);
157 if (apn_len == 0 || apn_len > 100) {
158 ofono_error("%s: invalid apn length: %d",
159 __func__,
160 (int) apn_len);
161 goto error;
162 }
163
164 if (req->auth_type > RIL_AUTH_BOTH) {
165 ofono_error("%s: Invalid auth type: %d",
166 __func__,
167 req->auth_type);
168 goto error;
169 }
170
171 protocol_str = ril_ofono_protocol_to_ril_string(req->protocol);
172 if (protocol_str == NULL) {
173 ofono_error("%s: Invalid protocol: %d",
174 __func__,
175 req->protocol);
176 goto error;
177 }
178
179 parcel_init(rilp);
180
181 parcel_w_int32(rilp, SETUP_DATA_CALL_PARAMS);
182
183 tech_str = g_strdup_printf("%d", req->tech);
184 parcel_w_string(rilp, (char *) tech_str);
185 parcel_w_string(rilp, (char *) profile_str);
186 parcel_w_string(rilp, (char *) req->apn);
187 parcel_w_string(rilp, (char *) req->username);
188 parcel_w_string(rilp, (char *) req->password);
189
190 auth_str = g_strdup_printf("%d", req->auth_type);
191 parcel_w_string(rilp, (char *) auth_str);
192 parcel_w_string(rilp, (char *) protocol_str);
193
194 g_ril_append_print_buf(gril,
195 "(%s,%s,%s,%s,%s,%s,%s)",
196 tech_str,
197 profile_str,
198 req->apn,
199 req->username,
200 req->password,
201 auth_str,
202 protocol_str);
203
204 g_free(tech_str);
205 g_free(auth_str);
206
207 OFONO_NO_ERROR(error);
208 return TRUE;
209
210error:
211 OFONO_EINVAL(error);
212 return FALSE;
213}
0214
=== added file 'gril/grilrequest.h'
--- gril/grilrequest.h 1970-01-01 00:00:00 +0000
+++ gril/grilrequest.h 2013-07-28 19:18:23 +0000
@@ -0,0 +1,63 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012-2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef __GRILREQUEST_H
24#define __GRILREQUEST_H
25
26#include <ofono/types.h>
27
28#include "gril.h"
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34struct req_deactivate_data_call {
35 guint cid;
36 guint reason;
37};
38
39struct req_setup_data_call {
40 guint tech;
41 guint data_profile;
42 gchar *apn;
43 gchar *username;
44 gchar *password;
45 guint auth_type;
46 guint protocol;
47};
48
49gboolean g_ril_request_deactivate_data_call(GRil *gril,
50 const struct req_deactivate_data_call *req,
51 struct parcel *rilp,
52 struct ofono_error *error);
53
54gboolean g_ril_request_setup_data_call(GRil *gril,
55 const struct req_setup_data_call *req,
56 struct parcel *rilp,
57 struct ofono_error *error);
58
59#ifdef __cplusplus
60}
61#endif
62
63#endif /* __GRILREQUEST_H */
064
=== added file 'gril/grilunsol.c'
--- gril/grilunsol.c 1970-01-01 00:00:00 +0000
+++ gril/grilunsol.c 2013-07-28 19:18:23 +0000
@@ -0,0 +1,158 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012-2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdio.h>
28#include <ctype.h>
29#include <errno.h>
30#include <string.h>
31
32#include <glib.h>
33
34#include <ofono/log.h>
35#include <ofono/modem.h>
36#include <ofono/gprs-context.h>
37
38#include "grilunsol.h"
39
40/* Minimum size is two int32s version/number of calls */
41#define MIN_DATA_CALL_LIST_SIZE 8
42
43static gint data_call_compare(gconstpointer a, gconstpointer b)
44{
45 const struct data_call *ca = a;
46 const struct data_call *cb = b;
47
48 if (ca->cid < cb->cid)
49 return -1;
50
51 if (ca->cid > cb->cid)
52 return 1;
53
54 return 0;
55}
56
57static void free_data_call(gpointer data, gpointer user_data)
58{
59 struct data_call *call = data;
60
61 if (call) {
62 g_free(call->type);
63 g_free(call->ifname);
64 g_free(call->addresses);
65 g_free(call->dnses);
66 g_free(call->gateways);
67 g_free(call);
68 }
69}
70
71void g_ril_unsol_free_data_call_list(struct unsol_data_call_list *unsol)
72{
73 if (unsol) {
74 g_slist_foreach(unsol->call_list, (GFunc) free_data_call, NULL);
75 g_slist_free(unsol->call_list);
76 g_free(unsol);
77 }
78}
79
80struct unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
81 struct ril_msg *message,
82 struct ofono_error *error)
83{
84 struct data_call *call;
85 struct parcel rilp;
86 struct unsol_data_call_list *reply =
87 g_new0(struct unsol_data_call_list, 1);
88 int i;
89
90 DBG("");
91
92 OFONO_NO_ERROR(error);
93
94 if (message->buf_len < MIN_DATA_CALL_LIST_SIZE) {
95 ofono_error("%s: message too small: %d",
96 __func__,
97 (int) message->buf_len);
98 OFONO_EINVAL(error);
99 goto error;
100 }
101
102 g_ril_init_parcel(message, &rilp);
103
104 /*
105 * ril.h documents the reply to a RIL_REQUEST_DATA_CALL_LIST
106 * as being an array of RIL_Data_Call_Response_v6 structs,
107 * however in reality, the response also includes a version
108 * to start.
109 */
110 reply->version = parcel_r_int32(&rilp);
111 reply->num = parcel_r_int32(&rilp);
112
113 g_ril_append_print_buf(gril,
114 "(version=%d,num=%d",
115 reply->version,
116 reply->num);
117
118 for (i = 0; i < reply->num; i++) {
119 call = g_new0(struct data_call, 1);
120
121 call->status = parcel_r_int32(&rilp);
122 call->retry = parcel_r_int32(&rilp);
123 call->cid = parcel_r_int32(&rilp);
124 call->active = parcel_r_int32(&rilp);
125
126 call->type = parcel_r_string(&rilp);
127 call->ifname = parcel_r_string(&rilp);
128 call->addresses = parcel_r_string(&rilp);
129 call->dnses = parcel_r_string(&rilp);
130 call->gateways = parcel_r_string(&rilp);
131
132 g_ril_append_print_buf(gril,
133 "%s [status=%d,retry=%d,cid=%d,"
134 "active=%d,type=%s,ifname=%s,"
135 "address=%s,dns=%s,gateways=%s]",
136 print_buf,
137 call->status,
138 call->retry,
139 call->cid,
140 call->active,
141 call->type,
142 call->ifname,
143 call->addresses,
144 call->dnses,
145 call->gateways);
146
147 reply->call_list =
148 g_slist_insert_sorted(reply->call_list,
149 call,
150 data_call_compare);
151 }
152
153 g_ril_append_print_buf(gril, "%s}", print_buf);
154 g_ril_print_unsol(gril, message);
155
156error:
157 return reply;
158}
0159
=== added file 'gril/grilunsol.h'
--- gril/grilunsol.h 1970-01-01 00:00:00 +0000
+++ gril/grilunsol.h 2013-07-28 19:18:23 +0000
@@ -0,0 +1,62 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012-2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef __GRILUNSOL_H
24#define __GRILUNSOL_H
25
26#include <ofono/types.h>
27
28#include "gril.h"
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34struct unsol_data_call_list {
35 guint version;
36 guint num;
37 GSList *call_list;
38};
39
40struct data_call {
41 guint status;
42 guint retry;
43 guint cid;
44 guint active;
45 char *type;
46 char *ifname;
47 char *addresses;
48 char *dnses;
49 char *gateways;
50};
51
52void g_ril_unsol_free_data_call_list(struct unsol_data_call_list *unsol);
53
54struct unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
55 struct ril_msg *message,
56 struct ofono_error *error);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif /* __GRILUNSOL_H */
063
=== modified file 'gril/grilutil.c'
--- gril/grilutil.c 2013-05-25 03:31:48 +0000
+++ gril/grilutil.c 2013-07-28 19:18:23 +0000
@@ -30,9 +30,56 @@
3030
31#include <glib.h>31#include <glib.h>
3232
33#include <ofono/modem.h>
34#include <ofono/gprs-context.h>
35#include <ofono/types.h>
36
33#include "grilutil.h"37#include "grilutil.h"
38#include "parcel.h"
34#include "ril_constants.h"39#include "ril_constants.h"
3540
41/* Constants used by CALL_LIST, and SETUP_DATA_CALL RIL requests */
42#define PROTO_IP_STR "IP"
43#define PROTO_IPV6_STR "IPV6"
44#define PROTO_IPV4V6_STR "IPV4V6"
45
46const char *ril_ofono_protocol_to_ril_string(guint protocol)
47{
48 char *result;
49
50 switch (protocol) {
51 case OFONO_GPRS_PROTO_IPV6:
52 result = PROTO_IPV6_STR;
53 break;
54 case OFONO_GPRS_PROTO_IPV4V6:
55 result = PROTO_IPV4V6_STR;
56 break;
57 case OFONO_GPRS_PROTO_IP:
58 result = PROTO_IP_STR;
59 break;
60 default:
61 result = NULL;
62 }
63
64 return result;
65}
66
67int ril_protocol_string_to_ofono_protocol(gchar *protocol_str)
68{
69 int result;
70
71 if (g_strcmp0(protocol_str, PROTO_IPV6_STR) == 0)
72 result = OFONO_GPRS_PROTO_IPV6;
73 else if (g_strcmp0(protocol_str, PROTO_IPV4V6_STR) == 0)
74 result = OFONO_GPRS_PROTO_IPV4V6;
75 else if (g_strcmp0(protocol_str, PROTO_IP_STR) == 0)
76 result = OFONO_GPRS_PROTO_IP;
77 else
78 result = -1;
79
80 return result;
81}
82
36const char *ril_appstate_to_string(int app_state)83const char *ril_appstate_to_string(int app_state)
37{84{
38 switch (app_state) {85 switch (app_state) {
3986
=== modified file 'gril/grilutil.h'
--- gril/grilutil.h 2013-05-25 03:31:48 +0000
+++ gril/grilutil.h 2013-07-28 19:18:23 +0000
@@ -23,12 +23,16 @@
23#ifndef __GRILUTIL_H23#ifndef __GRILUTIL_H
24#define __GRILUTIL_H24#define __GRILUTIL_H
2525
26#ifdef __cplusplus
27extern "C" {
28#endif
29
26#include "gfunc.h"30#include "gfunc.h"
2731#include "parcel.h"
28#ifdef __cplusplus32#include "gril.h"
29extern "C" {33
30#endif34const char *ril_ofono_protocol_to_ril_string(guint protocol);
3135int ril_protocol_string_to_ofono_protocol(gchar *protocol_str);
32const char *ril_appstate_to_string(int app_state);36const char *ril_appstate_to_string(int app_state);
33const char *ril_apptype_to_string(int app_type);37const char *ril_apptype_to_string(int app_type);
34const char *ril_cardstate_to_string(int card_state);38const char *ril_cardstate_to_string(int card_state);
3539
=== modified file 'gril/parcel.c'
--- gril/parcel.c 2013-05-24 22:02:28 +0000
+++ gril/parcel.c 2013-07-28 19:18:23 +0000
@@ -82,11 +82,9 @@
82{82{
83 for (;;) {83 for (;;) {
8484
85 /*85 DBG("parcel_w_int32(%d): offset = %d, cap = %d, size = %d\n",
86 * TODO: make conditional:86 val, p->offset, p->capacity, p->size);
87 * DBG("parcel_w_int32(%d): offset = %d, cap = %d, size = %d",87
88 * val, p->offset, p->capacity, p->size);
89 */
90 if (p->offset + sizeof(int32_t) < p->capacity) {88 if (p->offset + sizeof(int32_t) < p->capacity) {
91 /* There's enough space */89 /* There's enough space */
92 *((int32_t *) (p->data + p->offset)) = val;90 *((int32_t *) (p->data + p->offset)) = val;
@@ -106,6 +104,7 @@
106 gunichar2 *gs16;104 gunichar2 *gs16;
107 glong gs16_len;105 glong gs16_len;
108 size_t len;106 size_t len;
107 size_t gs16_size;
109108
110 if (str == NULL) {109 if (str == NULL) {
111 parcel_w_int32(p, -1);110 parcel_w_int32(p, -1);
@@ -118,27 +117,24 @@
118 return -1;117 return -1;
119 }118 }
120119
121 len = (gs16_len + 1) * sizeof(char16_t);120 gs16_size = gs16_len * sizeof(char16_t);
121 len = gs16_size + sizeof(char16_t);
122 for (;;) {122 for (;;) {
123 size_t padded = PAD_SIZE(len);123 size_t padded = PAD_SIZE(len);
124 /*124
125 * TODO: make conditional:125 DBG("parcel_w_string(\"%s\"): len %d offset %d, cap %d, size %d",
126 * DBG("parcel_w_string(\"%s\"): offset %d, cap %d, size %d",126 str, p->offset, p->capacity, p->size);
127 * str, p->offset, p->capacity, p->size);
128 */
129 if (p->offset + len < p->capacity) {127 if (p->offset + len < p->capacity) {
130 /* There's enough space */128 /* There's enough space */
131 memcpy(p->data + p->offset, gs16,129 memcpy(p->data + p->offset, gs16, gs16_size);
132 gs16_len * sizeof(char16_t));130 *((char16_t *) (p->data + p->offset + gs16_size)) = 0;
133 *((char16_t *) (p->data + p->offset + len)) = 0;
134 p->offset += padded;131 p->offset += padded;
135 p->size += padded;132 p->size += padded;
136 if (padded != len) {133 if (padded != len) {
137 /*134
138 * TODO: make conditional:135 DBG("Writing %d bytes, padded to %d\n",
139 * DBG("Writing %d bytes, padded to %d",136 len, padded);
140 * len, padded);137
141 */
142#if BYTE_ORDER == BIG_ENDIAN138#if BYTE_ORDER == BIG_ENDIAN
143 static const uint32_t mask[4] = {139 static const uint32_t mask[4] = {
144 0x00000000, 0xffffff00,140 0x00000000, 0xffffff00,
145141
=== modified file 'gril/ril_constants.h'
--- gril/ril_constants.h 2013-05-24 22:03:27 +0000
+++ gril/ril_constants.h 2013-07-28 19:18:23 +0000
@@ -76,12 +76,24 @@
76#define RADIO_TECH_HSPAP 1576#define RADIO_TECH_HSPAP 15
77#define RADIO_TECH_GSM 1677#define RADIO_TECH_GSM 16
7878
79/* see RIL_REQUEST_DEACTIVATE_DATA_CALL parameter*/
80#define RIL_DEACTIVATE_DATA_CALL_NO_REASON 0
81#define RIL_DEACTIVATE_DATA_CALL_RADIO_SHUTDOWN 1
82
79/* See RIL_REQUEST_SETUP_DATA_CALL */83/* See RIL_REQUEST_SETUP_DATA_CALL */
8084
81#define RIL_DATA_PROFILE_DEFAULT 085#define RIL_DATA_PROFILE_DEFAULT 0
82#define RIL_DATA_PROFILE_TETHERED 186#define RIL_DATA_PROFILE_TETHERED 1
87#define RIL_DATA_PROFILE_IMS 2
88#define RIL_DATA_PROFILE_FOTA 3 /* FOTA = Firmware Over the Air */
89#define RIL_DATA_PROFILE_CBS 4
83#define RIL_DATA_PROFILE_OEM_BASE 1000 /* Start of OEM-specific profiles */90#define RIL_DATA_PROFILE_OEM_BASE 1000 /* Start of OEM-specific profiles */
8491
92#define RIL_AUTH_NONE 0
93#define RIL_AUTH_PAP 1
94#define RIL_AUTH_CHAP 2
95#define RIL_AUTH_BOTH 3
96
85/* SIM card states */97/* SIM card states */
86#define RIL_CARDSTATE_ABSENT 098#define RIL_CARDSTATE_ABSENT 0
87#define RIL_CARDSTATE_PRESENT 199#define RIL_CARDSTATE_PRESENT 1
88100
=== modified file 'include/types.h'
--- include/types.h 2012-08-22 19:59:08 +0000
+++ include/types.h 2013-07-28 19:18:23 +0000
@@ -70,6 +70,16 @@
70 int error;70 int error;
71};71};
7272
73#define OFONO_EINVAL(error) do { \
74 error->type = OFONO_ERROR_TYPE_FAILURE; \
75 error->error = -EINVAL; \
76} while (0)
77
78#define OFONO_NO_ERROR(error) do { \
79 error->type = OFONO_ERROR_TYPE_NO_ERROR; \
80 error->error = 0; \
81} while (0)
82
73#define OFONO_MAX_PHONE_NUMBER_LENGTH 8083#define OFONO_MAX_PHONE_NUMBER_LENGTH 80
74#define OFONO_MAX_CALLER_NAME_LENGTH 8084#define OFONO_MAX_CALLER_NAME_LENGTH 80
7585
7686
=== added file 'unit/test-grilreply.c'
--- unit/test-grilreply.c 1970-01-01 00:00:00 +0000
+++ unit/test-grilreply.c 2013-07-28 19:18:23 +0000
@@ -0,0 +1,339 @@
1/*
2 *
3 * oFono - Open Source Telephony
4 *
5 * Copyright (C) 2013 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26#include <string.h>
27#include <stdio.h>
28#include <assert.h>
29#include <glib.h>
30#include <errno.h>
31
32#include <ofono/modem.h>
33#include <ofono/gprs-context.h>
34#include <ofono/types.h>
35
36#include "grilreply.h"
37
38/*
39 * TODO: It may make sense to split this file into
40 * domain-specific files ( eg. test-grilreply-gprs-context.c )
41 * once more tests are added.
42 */
43
44static const struct ril_msg reply_data_call_invalid_1 = {
45 .buf = "",
46 .buf_len = 0,
47};
48
49/*
50 * The following hexadecimal data equates te the following
51 * RIL_REQUEST_SETUP_DATA_CALL reply parameters:
52 *
53 * {version=2,num=2 [status=0,retry=-1,cid=0,active=2,type=IP}
54 * Parcel is truncated, as num=2 should trigger a failure.
55 */
56static const guchar reply_data_call_invalid_parcel2[36] = {
57 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
59 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00
60};
61
62static const struct ril_msg reply_data_call_invalid_2 = {
63 .buf = (gchar *) &reply_data_call_invalid_parcel2,
64 .buf_len = 36,
65};
66
67/*
68 * The following hexadecimal data is a binary representation of
69 * a parcel containing an invalid RIL_REQUEST_SETUP_DATA_CALL reply
70 * with a NULL string specified cfor 'type':
71 *
72 * {version=7,num=1 [status=0,retry=-1,cid=0,active=2,type=NULL
73 * ifname=rmnet_usb0,address=10.181.235.154/30,
74 * dns=172.16.145.103 172.16.145.103,gateways=10.181.235.153]}
75 */
76static const guchar reply_data_call_invalid_parcel3[196] = {
77 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
79 0xff, 0xff, 0xff, 0xff,
80 0x0a, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x65, 0x00,
81 0x74, 0x00, 0x5f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x30, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
83 0x2e, 0x00, 0x31, 0x00, 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00,
84 0x33, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x34, 0x00,
85 0x2f, 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
86 0x31, 0x00, 0x37, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00,
87 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00,
88 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x31, 0x00, 0x37, 0x00, 0x32, 0x00,
89 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00,
90 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x33, 0x00, 0x00, 0x00,
91 0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00,
92 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x33, 0x00, 0x35, 0x00,
93 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
94};
95
96static const struct ril_msg reply_data_call_invalid_3 = {
97 .buf = (gchar *) &reply_data_call_invalid_parcel3,
98 .buf_len = 196,
99};
100
101/*
102 * The following hexadecimal data is a binary representation of
103 * a parcel containing an invalid RIL_REQUEST_SETUP_DATA_CALL reply
104 * with a NULL string specified for 'ifname':
105 *
106 * {version=7,num=1 [status=0,retry=-1,cid=0,active=2,type=IP
107 * ifname=NULL,address=10.181.235.154/30,
108 * dns=172.16.145.103 172.16.145.103,gateways=10.181.235.153]}
109 */
110static const guchar reply_data_call_invalid_parcel4[190] = {
111 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
113 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0xff, 0xff, 0xff, 0xff, 0x11, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
115 0x2e, 0x00, 0x31, 0x00, 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00,
116 0x33, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x34, 0x00,
117 0x2f, 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
118 0x31, 0x00, 0x37, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00,
119 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00,
120 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x31, 0x00, 0x37, 0x00, 0x32, 0x00,
121 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00,
122 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x33, 0x00, 0x00, 0x00,
123 0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00,
124 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x33, 0x00, 0x35, 0x00,
125 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
126};
127
128static const struct ril_msg reply_data_call_invalid_4 = {
129 .buf = (gchar *) &reply_data_call_invalid_parcel4,
130 .buf_len = 190,
131};
132
133/*
134 * The following hexadecimal data is a binary representation of
135 * a parcel containing an invalid RIL_REQUEST_SETUP_DATA_CALL reply
136 * with a NULL string specified for 'address':
137 *
138 * {version=7,num=1 [status=0,retry=-1,cid=0,active=2,type=IP
139 * ifname=rmnet_usb0,address=NULL,
140 * dns=172.16.145.103 172.16.145.103,gateways=10.181.235.153]}
141 */
142static const guchar reply_data_call_invalid_parcel5[168] = {
143 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
145 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x0a, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x65, 0x00,
147 0x74, 0x00, 0x5f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x30, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1d, 0x00, 0x00, 0x00,
149 0x31, 0x00, 0x37, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00,
150 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00,
151 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x31, 0x00, 0x37, 0x00, 0x32, 0x00,
152 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00,
153 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x33, 0x00, 0x00, 0x00,
154 0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00,
155 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x33, 0x00, 0x35, 0x00,
156 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
157};
158
159static const struct ril_msg reply_data_call_invalid_5 = {
160 .buf = (gchar *) &reply_data_call_invalid_parcel5,
161 .buf_len = 168,
162};
163
164/*
165 * The following hexadecimal data represents a serialized Binder parcel
166 * instance containing an invalid RIL_REQUEST_SETUP_DATA_CALL reply
167 * with a NULL string specified for 'gateways':
168 *
169 * {version=7,num=1 [status=0,retry=-1,cid=0,active=2,type=IP
170 * ifname=rmnet_usb0,address=10.181.235.154/30,
171 * dns=172.16.145.103 172.16.145.103,gateways=NULL]}
172 */
173static const guchar reply_data_call_invalid_parcel6[180] = {
174 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
176 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x0a, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x65, 0x00,
178 0x74, 0x00, 0x5f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x30, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
180 0x2e, 0x00, 0x31, 0x00, 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00,
181 0x33, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x34, 0x00,
182 0x2f, 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
183 0x31, 0x00, 0x37, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00,
184 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00,
185 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x31, 0x00, 0x37, 0x00, 0x32, 0x00,
186 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00,
187 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x33, 0x00, 0x00, 0x00,
188 0xff, 0xff, 0xff, 0xff
189};
190
191static const struct ril_msg reply_data_call_invalid_6 = {
192 .buf = (gchar *) &reply_data_call_invalid_parcel6,
193 .buf_len = 180,
194};
195
196/*
197 * The following hexadecimal data represents a serialized Binder parcel
198 * instance containing an invalid RIL_REQUEST_SETUP_DATA_CALL reply with
199 * with a NULL string specified for 'dns':
200 *
201 * {version=7,num=1 [status=0,retry=-1,cid=0,active=2,type=IP
202 * ifname=rmnet_usb0,address=10.181.235.154/30,
203 * dns=NULL,gateways=10.181.235.153]}
204 */
205static const guchar reply_data_call_invalid_parcel7[144] = {
206 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
208 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x0a, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x65, 0x00,
210 0x74, 0x00, 0x5f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x30, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
212 0x2e, 0x00, 0x31, 0x00, 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00,
213 0x33, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x34, 0x00,
214 0x2f, 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
215 0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00,
216 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x33, 0x00, 0x35, 0x00,
217 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
218};
219
220static const struct ril_msg reply_data_call_invalid_7 = {
221 .buf = (gchar *) &reply_data_call_invalid_parcel7,
222 .buf_len = 144,
223};
224
225/*
226 * The following hexadecimal data represents a serialized Binder parcel
227 * instance containing a valid RIL_REQUEST_SETUP_DATA_CALL reply with the
228 * following parameters:
229 *
230 * {version=7,num=1 [status=0,retry=-1,cid=0,active=2,type=IP,
231 * ifname=rmnet_usb0,address=10.181.235.154/30,
232 * dns=172.16.145.103 172.16.145.103,gateways=10.181.235.153]}
233 */
234static const guchar reply_data_call_valid_parcel1[204] = {
235 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
237 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x0a, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x65, 0x00,
239 0x74, 0x00, 0x5f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x30, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
241 0x2e, 0x00, 0x31, 0x00, 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00,
242 0x33, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x34, 0x00,
243 0x2f, 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
244 0x31, 0x00, 0x37, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00,
245 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00,
246 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x31, 0x00, 0x37, 0x00, 0x32, 0x00,
247 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00,
248 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x33, 0x00, 0x00, 0x00,
249 0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00,
250 0x38, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x33, 0x00, 0x35, 0x00,
251 0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
252};
253
254static const struct ril_msg reply_data_call_valid_1 = {
255 .buf = (gchar *) &reply_data_call_valid_parcel1,
256 .buf_len = 204,
257 .unsolicited = FALSE,
258 .req = RIL_REQUEST_SETUP_DATA_CALL,
259 .serial_no = 0,
260 .error = 0,
261};
262
263static void test_reply_data_call_invalid(gconstpointer data)
264{
265 /* TODO: fix de-const cast... */
266 struct ril_msg *message = (struct ril_msg *) data;
267 struct ofono_error error;
268 struct reply_setup_data_call *reply;
269
270 reply = g_ril_reply_parse_data_call(NULL, message, &error);
271 g_assert(reply != NULL);
272 g_ril_reply_free_setup_data_call(reply);
273
274 g_assert(error.type == OFONO_ERROR_TYPE_FAILURE &&
275 error.error == -EINVAL);
276}
277
278static void test_reply_data_call_valid(gconstpointer data)
279{
280 /* TODO: fix de-const cast... */
281 struct ril_msg *message = (struct ril_msg *) data;
282 struct ofono_error error;
283 struct reply_setup_data_call *reply;
284
285 reply = g_ril_reply_parse_data_call(NULL, message, &error);
286 g_assert(reply != NULL);
287 g_ril_reply_free_setup_data_call(reply);
288
289 g_assert(error.type == OFONO_ERROR_TYPE_NO_ERROR &&
290 error.error == 0);
291}
292
293int main(int argc, char **argv)
294{
295 g_test_init(&argc, &argv, NULL);
296
297 g_test_add_data_func("/testgrilreply/gprs-context: "
298 "invalid SETUP_DATA_CALL Test 1",
299 &reply_data_call_invalid_1,
300 test_reply_data_call_invalid);
301
302 g_test_add_data_func("/testgrilreply/gprs-context: "
303 "invalid SETUP_DATA_CALL Test 2",
304 &reply_data_call_invalid_2,
305 test_reply_data_call_invalid);
306
307 g_test_add_data_func("/testgrilreply/gprs-context: "
308 "invalid SETUP_DATA_CALL Test 3",
309 &reply_data_call_invalid_3,
310 test_reply_data_call_invalid);
311
312 g_test_add_data_func("/testgrilreply/gprs-context: "
313 "invalid SETUP_DATA_CALL Test 4",
314 &reply_data_call_invalid_4,
315 test_reply_data_call_invalid);
316
317 g_test_add_data_func("/testgrilreply/gprs-context: "
318 "invalid SETUP_DATA_CALL Test 5",
319 &reply_data_call_invalid_5,
320 test_reply_data_call_invalid);
321
322 g_test_add_data_func("/testgrilreply/gprs-context: "
323 "invalid SETUP_DATA_CALL Test 6",
324 &reply_data_call_invalid_6,
325 test_reply_data_call_invalid);
326
327 g_test_add_data_func("/testgrilreply/gprs-context: "
328 "invalid SETUP_DATA_CALL Test 7",
329 &reply_data_call_invalid_7,
330 test_reply_data_call_invalid);
331
332 g_test_add_data_func("/testgrilreply/gprs-context: "
333 "valid SETUP_DATA_CALL Test 1",
334 &reply_data_call_valid_1,
335 test_reply_data_call_valid);
336
337
338 return g_test_run();
339}
0340
=== added file 'unit/test-grilrequest.c'
--- unit/test-grilrequest.c 1970-01-01 00:00:00 +0000
+++ unit/test-grilrequest.c 2013-07-28 19:18:23 +0000
@@ -0,0 +1,312 @@
1/*
2 *
3 * oFono - Open Source Telephony
4 *
5 * Copyright (C) 2013 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26#include <string.h>
27#include <stdio.h>
28#include <assert.h>
29#include <glib.h>
30#include <errno.h>
31
32#include <ofono/modem.h>
33#include <ofono/gprs-context.h>
34#include <ofono/types.h>
35
36#include "grilrequest.h"
37
38struct request_test_data {
39 gconstpointer request;
40 guchar *parcel_data;
41 gsize parcel_size;
42};
43
44/*
45 * TODO: It may make sense to split this file into
46 * domain-specific files ( eg. test-grilrequest-gprs-context.c )
47 * once more tests are added.
48 */
49
50static const struct req_deactivate_data_call req_deact_data_call_invalid_1 = {
51 .cid = 1,
52 .reason = 10,
53};
54
55/*
56 * The following hexadecimal data represents a serialized Binder parcel
57 * instance containing a valid RIL_REQUEST_DEACTIVATE_DATA_CALL message
58 * with the following parameters:
59 *
60 * (cid=1,reason=0)
61 */
62static const guchar req_deact_data_call_valid_parcel1[20] = {
63 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
64 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00
65};
66
67static const struct req_deactivate_data_call req_deact_data_call_valid_1 = {
68 .cid = 1,
69 .reason = RIL_DEACTIVATE_DATA_CALL_NO_REASON,
70};
71
72static const struct request_test_data deact_data_call_valid_test_1 = {
73 .request = &req_deact_data_call_valid_1,
74 .parcel_data = (guchar *) &req_deact_data_call_valid_parcel1,
75 .parcel_size = 20,
76};
77
78
79static const struct req_setup_data_call req_setup_data_call_invalid_1 = {
80 .tech = RADIO_TECH_UNKNOWN,
81};
82
83static const struct req_setup_data_call req_setup_data_call_invalid_2 = {
84 .tech = 2112,
85};
86
87static const struct req_setup_data_call req_setup_data_call_invalid_3 = {
88 .tech = RADIO_TECH_GPRS,
89 .data_profile = 5,
90};
91
92static const struct req_setup_data_call req_setup_data_call_invalid_4 = {
93 .tech = RADIO_TECH_GPRS,
94 .data_profile = RIL_DATA_PROFILE_DEFAULT,
95 .apn = NULL,
96};
97
98static const struct req_setup_data_call req_setup_data_call_invalid_5 = {
99 .tech = RADIO_TECH_GPRS,
100 .data_profile = RIL_DATA_PROFILE_DEFAULT,
101 .apn = "",
102};
103
104static const struct req_setup_data_call req_setup_data_call_invalid_6 = {
105 .tech = RADIO_TECH_GPRS,
106 .data_profile = RIL_DATA_PROFILE_DEFAULT,
107 .apn = "",
108 .apn = "12345678901234567890123456789012345678901234567890"
109 "123456789012345678901234567890123456789012345678901",
110};
111
112static const struct req_setup_data_call req_setup_data_call_invalid_7 = {
113 .tech = RADIO_TECH_GPRS,
114 .data_profile = RIL_DATA_PROFILE_DEFAULT,
115 .apn = "test.apn",
116 .auth_type = 4,
117};
118
119static const struct req_setup_data_call req_setup_data_call_invalid_8 = {
120 .tech = RADIO_TECH_GPRS,
121 .data_profile = RIL_DATA_PROFILE_DEFAULT,
122 .apn = "test.apn",
123 .auth_type = RIL_AUTH_BOTH,
124 .protocol = 3,
125};
126
127static const struct req_setup_data_call req_setup_data_call_valid_1 = {
128 .tech = RADIO_TECH_GPRS,
129 .data_profile = RIL_DATA_PROFILE_DEFAULT,
130 .apn = "test.apn",
131 .username = NULL,
132 .password = NULL,
133 .auth_type = RIL_AUTH_BOTH,
134 .protocol = OFONO_GPRS_PROTO_IP,
135
136};
137
138static const struct req_setup_data_call req_setup_data_call_valid_2 = {
139 .tech = RADIO_TECH_GPRS,
140 .data_profile = RIL_DATA_PROFILE_DEFAULT,
141 .apn = "test.apn",
142 .username = "",
143 .password = "",
144 .auth_type = RIL_AUTH_NONE,
145 .protocol = OFONO_GPRS_PROTO_IP,
146};
147
148static const struct req_setup_data_call req_setup_data_call_valid_3 = {
149 .tech = RADIO_TECH_GPRS,
150 .data_profile = RIL_DATA_PROFILE_DEFAULT,
151 .apn = "test.apn",
152 .username = "phablet",
153 .password = "phablet",
154 .auth_type = RIL_AUTH_BOTH,
155 .protocol = OFONO_GPRS_PROTO_IPV4V6,
156};
157
158static const struct req_setup_data_call req_setup_data_call_valid_4 = {
159 .tech = RADIO_TECH_GPRS,
160 .data_profile = RIL_DATA_PROFILE_DEFAULT,
161 .apn = "test.apn",
162 .username = "phablet",
163 .password = "phablet",
164 .auth_type = RIL_AUTH_BOTH,
165 .protocol = OFONO_GPRS_PROTO_IPV6,
166};
167
168static void test_deactivate_data_call_invalid(gconstpointer data)
169{
170 const struct req_deactivate_data_call *request = data;
171 gboolean result;
172 struct parcel rilp;
173 struct ofono_error error;
174
175 /*
176 * No parcel_init needed, as these tests all fail during
177 * param validation
178 */
179 result = g_ril_request_deactivate_data_call(NULL, request, &rilp, &error);
180 g_assert(result == FALSE);
181 g_assert(error.type == OFONO_ERROR_TYPE_FAILURE &&
182 error.error == -EINVAL);
183}
184
185static void test_deactivate_data_call_valid(gconstpointer data)
186{
187 const struct request_test_data *test_data = data;
188 const struct req_deactivate_data_call *request = test_data->request;
189 gboolean result;
190 struct parcel rilp;
191 struct ofono_error error;
192
193 result = g_ril_request_deactivate_data_call(NULL, request, &rilp, &error);
194 g_assert(result == TRUE);
195 g_assert(error.type == OFONO_ERROR_TYPE_NO_ERROR &&
196 error.error == 0);
197
198 g_assert(!memcmp(rilp.data, test_data->parcel_data, test_data->parcel_size));
199
200 parcel_free(&rilp);
201}
202
203static void test_request_setup_data_call_invalid(gconstpointer data)
204{
205 const struct req_setup_data_call *request = data;
206 gboolean result;
207 struct parcel rilp;
208 struct ofono_error error;
209
210 /*
211 * No parcel_init needed, as these tests all fail during
212 * param validation
213 */
214 result = g_ril_request_setup_data_call(NULL, request, &rilp, &error);
215 g_assert(result == FALSE);
216 g_assert(error.type == OFONO_ERROR_TYPE_FAILURE &&
217 error.error == -EINVAL);
218}
219
220static void test_request_setup_data_call_valid(gconstpointer data)
221{
222 const struct req_setup_data_call *request = data;
223 gboolean result;
224 struct parcel rilp;
225 struct ofono_error error;
226
227 result = g_ril_request_setup_data_call(NULL, request, &rilp, &error);
228 g_assert(result == TRUE);
229 g_assert(error.type == OFONO_ERROR_TYPE_NO_ERROR &&
230 error.error == 0);
231
232 parcel_free(&rilp);
233
234 /* TODO: add unit 3 tests to validate binary parcel result */
235}
236
237int main(int argc, char **argv)
238{
239 g_test_init(&argc, &argv, NULL);
240
241 g_test_add_data_func("/testgrilrequest/gprs-context: "
242 "invalid DEACTIVATE_DATA_CALL Test 1",
243 &req_deact_data_call_invalid_1,
244 test_deactivate_data_call_invalid);
245
246 g_test_add_data_func("/testgrilrequest/gprs-context: "
247 "valid DEACTIVATE_DATA_CALL Test 1",
248 &deact_data_call_valid_test_1,
249 test_deactivate_data_call_valid);
250
251 g_test_add_data_func("/testgrilrequest/gprs-context: "
252 "invalid SETUP_DATA_CALL Test 1",
253 &req_setup_data_call_invalid_1,
254 test_request_setup_data_call_invalid);
255
256 g_test_add_data_func("/testgrilrequest/gprs-context: "
257 "invalid SETUP_DATA_CALL Test 2",
258 &req_setup_data_call_invalid_2,
259 test_request_setup_data_call_invalid);
260
261 g_test_add_data_func("/testgrilrequest/gprs-context: "
262 "invalid SETUP_DATA_CALL Test 3",
263 &req_setup_data_call_invalid_3,
264 test_request_setup_data_call_invalid);
265
266 g_test_add_data_func("/testgrilrequest/gprs-context: "
267 "invalid SETUP_DATA_CALL Test 4",
268 &req_setup_data_call_invalid_4,
269 test_request_setup_data_call_invalid);
270
271 g_test_add_data_func("/testgrilrequest/gprs-context: "
272 "invalid SETUP_DATA_CALL Test 5",
273 &req_setup_data_call_invalid_5,
274 test_request_setup_data_call_invalid);
275
276 g_test_add_data_func("/testgrilrequest/gprs-context: "
277 "invalid SETUP_DATA_CALL Test 6",
278 &req_setup_data_call_invalid_6,
279 test_request_setup_data_call_invalid);
280
281 g_test_add_data_func("/testgrilrequest/gprs-context: "
282 "invalid SETUP_DATA_CALL Test 7",
283 &req_setup_data_call_invalid_7,
284 test_request_setup_data_call_invalid);
285
286 g_test_add_data_func("/testgrilrequest/gprs-context: "
287 "invalid SETUP_DATA_CALL Test 8",
288 &req_setup_data_call_invalid_8,
289 test_request_setup_data_call_invalid);
290
291 g_test_add_data_func("/testgrilrequest/gprs-context: "
292 "valid SETUP_DATA_CALL Test 1",
293 &req_setup_data_call_valid_1,
294 test_request_setup_data_call_valid);
295
296 g_test_add_data_func("/testgrilrequest/gprs-context: "
297 "valid SETUP_DATA_CALL Test 2",
298 &req_setup_data_call_valid_2,
299 test_request_setup_data_call_valid);
300
301 g_test_add_data_func("/testgrilrequest/gprs-context: "
302 "valid SETUP_DATA_CALL Test 3",
303 &req_setup_data_call_valid_3,
304 test_request_setup_data_call_valid);
305
306 g_test_add_data_func("/testgrilrequest/gprs-context: "
307 "valid SETUP_DATA_CALL Test 4",
308 &req_setup_data_call_valid_4,
309 test_request_setup_data_call_valid);
310
311 return g_test_run();
312}
0313
=== added file 'unit/test-grilunsol.c'
--- unit/test-grilunsol.c 1970-01-01 00:00:00 +0000
+++ unit/test-grilunsol.c 2013-07-28 19:18:23 +0000
@@ -0,0 +1,138 @@
1/*
2 *
3 * oFono - Open Source Telephony
4 *
5 * Copyright (C) 2013 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26#include <string.h>
27#include <stdio.h>
28#include <assert.h>
29#include <glib.h>
30#include <errno.h>
31
32#include <ofono/modem.h>
33#include <ofono/gprs-context.h>
34#include <ofono/types.h>
35
36#include "gril.h"
37#include "grilunsol.h"
38
39/*
40 * TODO: It may make sense to split this file into
41 * domain-specific files ( eg. test-grilrequest-gprs-context.c )
42 * once more tests are added.
43 */
44
45static const struct ril_msg unsol_data_call_list_changed_invalid_1 = {
46 .buf = "",
47 .buf_len = 0,
48 .unsolicited = TRUE,
49 .req = RIL_UNSOL_DATA_CALL_LIST_CHANGED,
50 .serial_no = 0,
51 .error = 0,
52};
53
54/*
55 * The following hexadecimal data represents a serialized Binder parcel
56 * instance containing a valid RIL_UNSOL_DATA_CALL_LIST_CHANGED message
57 * with the following parameters:
58 *
59 * (version=7,num=1 [status=0,retry=-1,cid=0,active=1,type=IP,
60 * ifname=rmnet_usb0,address=10.209.114.102/30,
61 * dns=172.16.145.103 172.16.145.103,gateways=10.209.114.101]}
62 */
63static const guchar unsol_data_call_list_changed_parcel1[216] = {
64 0x00, 0x00, 0x00, 0xd4, 0x01, 0x00, 0x00, 0x00, 0xf2, 0x03, 0x00, 0x00,
65 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
67 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x0a, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x65, 0x00,
69 0x74, 0x00, 0x5f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x30, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
71 0x2e, 0x00, 0x32, 0x00, 0x30, 0x00, 0x39, 0x00, 0x2e, 0x00, 0x31, 0x00,
72 0x31, 0x00, 0x34, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x32, 0x00,
73 0x2f, 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
74 0x31, 0x00, 0x37, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00,
75 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00,
76 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x31, 0x00, 0x37, 0x00, 0x32, 0x00,
77 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x34, 0x00,
78 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x33, 0x00, 0x00, 0x00,
79 0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x32, 0x00,
80 0x30, 0x00, 0x39, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x31, 0x00, 0x34, 0x00,
81 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
82};
83
84static const struct ril_msg unsol_data_call_list_changed_valid_1 = {
85 .buf = (gchar *) &unsol_data_call_list_changed_parcel1,
86 .buf_len = 216,
87 .unsolicited = TRUE,
88 .req = RIL_UNSOL_DATA_CALL_LIST_CHANGED,
89 .serial_no = 0,
90 .error = 0,
91};
92
93static void test_unsol_data_call_list_changed_invalid(gconstpointer data)
94{
95 /* TODO: fix de-const cast... */
96 const struct ril_msg *message = (struct ril_msg *) data;
97 struct ofono_error error;
98 struct unsol_data_call_list *unsol;
99
100 unsol = g_ril_unsol_parse_data_call_list(NULL, message, &error);
101 g_assert(unsol != NULL);
102 g_ril_unsol_free_data_call_list(unsol);
103
104 g_assert(error.type == OFONO_ERROR_TYPE_FAILURE &&
105 error.error == -EINVAL);
106}
107
108static void test_unsol_data_call_list_changed_valid(gconstpointer data)
109{
110 /* TODO: fix de-const cast... */
111 const struct ril_msg *message = (struct ril_msg *) data;
112 struct ofono_error error;
113 struct unsol_data_call_list *unsol;
114
115 unsol = g_ril_unsol_parse_data_call_list(NULL, message, &error);
116 g_assert(unsol != NULL);
117 g_ril_unsol_free_data_call_list(unsol);
118
119 g_assert(error.type == OFONO_ERROR_TYPE_NO_ERROR &&
120 error.error == 0);
121}
122
123int main(int argc, char **argv)
124{
125 g_test_init(&argc, &argv, NULL);
126
127 g_test_add_data_func("/testgrilrequest/gprs-context: "
128 "invalid DATA_CALL_LIST_CHANGED Test 1",
129 &unsol_data_call_list_changed_invalid_1,
130 test_unsol_data_call_list_changed_invalid);
131
132 g_test_add_data_func("/testgrilrequest/gprs-context: "
133 "valid DATA_CALL_LIST_CHANGED Test 1",
134 &unsol_data_call_list_changed_valid_1,
135 test_unsol_data_call_list_changed_valid);
136
137 return g_test_run();
138}

Subscribers

People subscribed via source and target branches