--- drivers/isimodem/gprs-context.c | 119 ++++++++++++++++++++++++--------------- 1 files changed, 73 insertions(+), 46 deletions(-)
diff --git a/drivers/isimodem/gprs-context.c b/drivers/isimodem/gprs-context.c index bbf7ca9..674d0ab 100644 --- a/drivers/isimodem/gprs-context.c +++ b/drivers/isimodem/gprs-context.c @@ -62,10 +62,7 @@ struct context_data { uint16_t gpds; /* GPDS object handle */ unsigned cid; /* oFono core context ID */ struct ofono_gprs_context *context; - union { - ofono_gprs_context_up_cb_t up_cb; - ofono_gprs_context_cb_t down_cb; - }; + ofono_gprs_context_cb_t cb; void *data; GIsiPEP *pep; @@ -112,15 +109,14 @@ typedef void (*ContextFailFunc)(struct context_data *cd); static void gprs_up_fail(struct context_data *cd) { - CALLBACK_WITH_FAILURE(cd->up_cb, NULL, 0, NULL, NULL, NULL, NULL, - cd->data); reset_context(cd); + CALLBACK_WITH_FAILURE(cd->cb, cd->data); } static void gprs_down_fail(struct context_data *cd) { - CALLBACK_WITH_FAILURE(cd->down_cb, cd->data); reset_context(cd); + CALLBACK_WITH_FAILURE(cd->cb, cd->data); } static gboolean check_resp(const GIsiMessage *msg, uint8_t id, size_t minlen, @@ -206,12 +202,12 @@ static void activate_ind_cb(const GIsiMessage *msg, void *opaque) { struct context_data *cd = opaque; GIsiSubBlockIter iter; + const char *dns[5]; + int dns_count = 0; char ifname[IF_NAMESIZE]; - char *ip = NULL; - char *pdns = NULL; - char *sdns = NULL; - const char *dns[3]; + char *ip_addr = NULL; + char *ipv6_addr = NULL; if (!check_ind(msg, 2, cd)) return; @@ -225,8 +221,6 @@ static void activate_ind_cb(const GIsiMessage *msg, void *opaque) switch (g_isi_sb_iter_get_id(&iter)) { - /* TODO: IPv6 address support */ - case GPDS_PDP_ADDRESS_INFO: if (!g_isi_sb_iter_get_byte(&iter, &addr_len, 3)) @@ -236,9 +230,15 @@ static void activate_ind_cb(const GIsiMessage *msg, void *opaque) 4)) goto error; - ip = alloca(INET_ADDRSTRLEN); - inet_ntop(AF_INET, (const void *)addr_value, ip, - INET_ADDRSTRLEN); + if (addr_len == 4) { + ip_addr = alloca(INET_ADDRSTRLEN); + inet_ntop(AF_INET, (const void *)addr_value, + ip_addr, INET_ADDRSTRLEN); + } else if (addr_len == 16) { + ipv6_addr = alloca(INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, (const void *)addr_value, + ipv6_addr, INET6_ADDRSTRLEN); + } break; case GPDS_PDNS_ADDRESS_INFO: @@ -250,9 +250,17 @@ static void activate_ind_cb(const GIsiMessage *msg, void *opaque) 4)) break; - pdns = alloca(INET_ADDRSTRLEN); - inet_ntop(AF_INET, (const void *)addr_value, pdns, - INET_ADDRSTRLEN); + if (addr_len == 4) { + char *addr = alloca(INET_ADDRSTRLEN); + inet_ntop(AF_INET, (const void *)addr_value, + addr, INET_ADDRSTRLEN); + dns[dns_count++] = addr; + } else if (addr_len == 16) { + char *addr = alloca(INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, (const void *)addr_value, + addr, INET6_ADDRSTRLEN); + dns[dns_count++] = addr; + } break; case GPDS_SDNS_ADDRESS_INFO: @@ -264,9 +272,17 @@ static void activate_ind_cb(const GIsiMessage *msg, void *opaque) 4)) break; - sdns = alloca(INET_ADDRSTRLEN); - inet_ntop(AF_INET, (const void *)addr_value, sdns, - INET_ADDRSTRLEN); + if (addr_len == 4) { + char *addr = alloca(INET_ADDRSTRLEN); + inet_ntop(AF_INET, (const void *)addr_value, + addr, INET_ADDRSTRLEN); + dns[dns_count++] = addr; + } else if (addr_len == 16) { + char *addr = alloca(INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, (const void *)addr_value, + addr, INET6_ADDRSTRLEN); + dns[dns_count++] = addr; + } break; default: @@ -279,26 +295,26 @@ static void activate_ind_cb(const GIsiMessage *msg, void *opaque) if (!g_isi_pep_get_ifname(cd->pep, ifname)) goto error; - dns[0] = pdns; - dns[1] = sdns; - dns[2] = 0; + ofono_gprs_context_set_interface(cd->context, ifname); - CALLBACK_WITH_SUCCESS(cd->up_cb, ifname, TRUE, (const char *)ip, - STATIC_IP_NETMASK, NULL, - dns, cd->data); - return; + if (ip_addr != NULL) { + ofono_gprs_context_set_ip_addrconf(cd->context, + OFONO_GPRS_ADDRCONF_STATIC); + ofono_gprs_context_set_ip_address(cd->context, ip_addr); + ofono_gprs_context_set_ip_netmask(cd->context, + STATIC_IP_NETMASK); + } -error: - gprs_up_fail(cd); -} + if (ipv6_addr != NULL) + ofono_gprs_context_set_ipv6_address(cd->context, ipv6_addr); -static void activate_fail_ind_cb(const GIsiMessage *msg, void *opaque) -{ - struct context_data *cd = opaque; + dns[dns_count] = 0; + ofono_gprs_context_set_dns_servers(cd->context, dns); - if (!check_ind(msg, 2, cd)) - return; + CALLBACK_WITH_SUCCESS(cd->cb, cd->data); + return; +error: gprs_up_fail(cd); } @@ -319,8 +335,6 @@ static void send_context_activate(GIsiClient *client, void *opaque) g_isi_client_ind_subscribe(client, GPDS_CONTEXT_ACTIVATE_IND, activate_ind_cb, cd); - g_isi_client_ind_subscribe(client, GPDS_CONTEXT_ACTIVATE_FAIL_IND, - activate_fail_ind_cb, cd); g_isi_client_ind_subscribe(client, GPDS_CONTEXT_DEACTIVATE_IND, deactivate_ind_cb, cd); @@ -479,7 +493,7 @@ static void create_pipe_cb(GIsiPipe *pipe) static void isi_gprs_activate_primary(struct ofono_gprs_context *gc, const struct ofono_gprs_primary_context *ctx, - ofono_gprs_context_up_cb_t cb, void *data) + ofono_gprs_context_cb_t cb, void *data) { struct context_data *cd = ofono_gprs_context_get_data(gc); @@ -487,8 +501,7 @@ static void isi_gprs_activate_primary(struct ofono_gprs_context *gc, if (cd == NULL || !cd->gpds) { /* GPDS is not reachable */ - CALLBACK_WITH_FAILURE(cb, NULL, 0, NULL, NULL, NULL, - NULL, data); + CALLBACK_WITH_FAILURE(cb, data); return; } @@ -499,12 +512,26 @@ static void isi_gprs_activate_primary(struct ofono_gprs_context *gc, } cd->cid = ctx->cid; - cd->up_cb = cb; + cd->cb = cb; cd->data = data; cd->pep = NULL; cd->pipe = NULL; cd->handle = INVALID_ID; - cd->type = GPDS_PDP_TYPE_IPV4; + + switch (ctx->proto) { + case OFONO_GPRS_PROTO_IP: + cd->type = GPDS_PDP_TYPE_IPV4; + break; + + case OFONO_GPRS_PROTO_IPV6: + cd->type = GPDS_PDP_TYPE_IPV6; + break; + + case OFONO_GPRS_PROTO_IPV4V6: + /* Not supported by modem */ + CALLBACK_WITH_FAILURE(cb, data); + return; + } if (strlen(ctx->apn) >= GPDS_MAX_APN_STRING_LENGTH || strlen(ctx->username) >= GPDS_MAX_USERNAME_LENGTH @@ -546,7 +573,7 @@ static void context_deactivate_cb(const GIsiMessage *msg, void *opaque) gprs_down_fail)) return; - CALLBACK_WITH_SUCCESS(cd->down_cb, cd->data); + CALLBACK_WITH_SUCCESS(cd->cb, cd->data); reset_context(cd); } @@ -564,7 +591,7 @@ static void isi_gprs_deactivate_primary(struct ofono_gprs_context *gc, if (cd == NULL) return; - cd->down_cb = cb; + cd->cb = cb; cd->data = data; msg[1] = cd->handle; -- 1.7.1 _______________________________________________ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono