Hi Jussi, On 03/09/2011 04:27 AM, Jussi Kangas wrote: > --- > Hi, > > Here is a fix for call forwarding issue Jarko found a while back. ( TODO > issue "Call forwarding state handling change" and mailing list > conversation "Ofono CF states not always correct" ). > > Br, > Jussi > > src/call-forwarding.c | 78 ++++++++++++++++++++++++++++++++++++++++++++----- > 1 files changed, 70 insertions(+), 8 deletions(-) > > diff --git a/src/call-forwarding.c b/src/call-forwarding.c > index d13f990..6f81296 100644 > --- a/src/call-forwarding.c > +++ b/src/call-forwarding.c > @@ -514,10 +514,24 @@ static DBusMessage *cf_get_properties_reply(DBusMessage *msg, > OFONO_PROPERTIES_ARRAY_SIGNATURE, > &dict); > > - for (i = 0; i < 4; i++) > - property_append_cf_conditions(&dict, cf->cf_conditions[i], > + if (cf->cf_conditions[CALL_FORWARDING_TYPE_UNCONDITIONAL] == 0) { Please use a comparison to NULL here instead of 0 > + DBG("Append all"); > + for (i = 0; i < 4; i++) > + property_append_cf_conditions(&dict, > + cf->cf_conditions[i], > + BEARER_CLASS_VOICE, > + cf_type_lut[i]); Please fix the indentation levels here, the lines following property_append... should all be the same indentation level. Also, we might want to skip the unconditional call forwarding settings here. > + } else { > + DBG("append only unconditional"); > + property_append_cf_conditions(&dict, > + cf->cf_conditions[CALL_FORWARDING_TYPE_UNCONDITIONAL], > + BEARER_CLASS_VOICE, > + cf_type_lut[0]); > + for (i = 1; i < 4; i++) > + property_append_cf_conditions(&dict, NULL, > BEARER_CLASS_VOICE, > cf_type_lut[i]); So I'm confused, the TODO entry says we should not return conditional entries if the unconditional call forwarding is set as they are now quiescent. Are you proposing we handle this a bit differently? > + } > > if ((cf->flags & CALL_FORWARDING_FLAG_CPHS_CFF) || > cf->cfis_record_id > 0) > @@ -682,8 +696,23 @@ static void set_query_cf_callback(const struct ofono_error *error, int total, > > static void set_query_next_cf_cond(struct ofono_call_forwarding *cf) > { > - cf->driver->query(cf, cf->query_next, BEARER_CLASS_DEFAULT, > - set_query_cf_callback, cf); > + DBusMessage *reply; > + > + while (cf->query_next != CALL_FORWARDING_TYPE_NOT_REACHABLE) { > + if (!cf->cf_conditions[cf->query_next]) { > + cf->driver->query(cf, cf->query_next, > + BEARER_CLASS_DEFAULT, > + set_query_cf_callback, cf); > + return; > + } else { > + cf->query_next++; > + if (cf->query_next == cf->query_end) > + break; > + } > + } > + > + reply = dbus_message_new_method_return(cf->pending); > + __ofono_dbus_pending_reply(&cf->pending, reply); Really lost here, > } > > static void set_property_callback(const struct ofono_error *error, void *data) > @@ -836,6 +865,7 @@ static void disable_conditional_callback(const struct ofono_error *error, > static void disable_all_callback(const struct ofono_error *error, void *data) > { > struct ofono_call_forwarding *cf = data; > + int i; > > if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { > DBG("Error occurred during erasure of all"); > @@ -848,6 +878,10 @@ static void disable_all_callback(const struct ofono_error *error, void *data) > /* Query all cf types */ > cf->query_next = CALL_FORWARDING_TYPE_UNCONDITIONAL; > cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE; > + > + for (i = 0; i < CALL_FORWARDING_TYPE_ALL; i++) > + cf->cf_conditions[i] = 0; > + For pointers please use NULL instead of 0. Why are we setting them to NULL here in the first place? And shouldn't you free the data? > set_query_next_cf_cond(cf); > } > > @@ -1014,8 +1048,25 @@ static void ss_set_query_cf_callback(const struct ofono_error *error, int total, > > static void ss_set_query_next_cf_cond(struct ofono_call_forwarding *cf) > { > - cf->driver->query(cf, cf->query_next, BEARER_CLASS_DEFAULT, > - ss_set_query_cf_callback, cf); > + DBusMessage *reply; > + > + while (cf->query_next != CALL_FORWARDING_TYPE_NOT_REACHABLE) { > + if (!cf->cf_conditions[cf->query_next]) { > + cf->driver->query(cf, cf->query_next, > + BEARER_CLASS_DEFAULT, > + ss_set_query_cf_callback, cf); > + return; > + } else { > + cf->query_next++; > + if (cf->query_next == cf->query_end) > + break; > + } > + } > + > + reply = cf_ss_control_reply(cf, cf->ss_req); > + __ofono_dbus_pending_reply(&cf->pending, reply); > + g_free(cf->ss_req); > + cf->ss_req = NULL; Again, very lost > } > > static void cf_ss_control_callback(const struct ofono_error *error, void *data) > @@ -1032,6 +1083,11 @@ static void cf_ss_control_callback(const struct ofono_error *error, void *data) > return; > } > > + if (cf->ss_req) { > + if (cf->ss_req->ss_type == SS_CONTROL_TYPE_ERASURE) > + cf->cf_conditions[cf->ss_req->cf_type] = 0; > + } > + > ss_set_query_next_cf_cond(cf); > } > > @@ -1180,8 +1236,14 @@ static gboolean cf_ss_control(int type, const char *sc, > cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE; > break; > case CALL_FORWARDING_TYPE_ALL_CONDITIONAL: > - cf->query_next = CALL_FORWARDING_TYPE_BUSY; > - cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE; I don't see how handling both these cases with the same code can work... > + case CALL_FORWARDING_TYPE_UNCONDITIONAL: > + if (type == SS_CONTROL_TYPE_REGISTRATION) { > + cf->query_next = cf->ss_req->cf_type; > + cf->query_end = cf->ss_req->cf_type; > + } else { > + cf->query_next = cf->ss_req->cf_type; > + cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE; > + } I'm a bit lost here, can you explain some more what you're trying to accomplish? > break; > default: > cf->query_next = cf->ss_req->cf_type; Regards, -Denis