Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #152 from jessi3py/bug-978071-ics
Browse files Browse the repository at this point in the history
Bug 978071 - support reporting IPv6 addresses. r=echen
  • Loading branch information
BavarianTomcat committed Sep 8, 2015
2 parents d70e4bf + 62de279 commit 067c08f
Showing 1 changed file with 67 additions and 22 deletions.
89 changes: 67 additions & 22 deletions telephony/android_modem.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,13 @@ typedef struct AVoiceCallRec {

typedef enum {
A_DATA_IP = 0,
A_DATA_PPP
A_DATA_PPP,
A_DATA_IPV6
} ADataType;

typedef struct {
struct in_addr in;
struct in6_addr in6;
} AInetAddrRec, *AInetAddr;

#define A_DATA_APN_SIZE 32
Expand Down Expand Up @@ -792,6 +794,36 @@ static int android_modem_state_load(QEMUFile *f, void *opaque, int version_id)
static int _amodem_num_rmnets = 0;
static ADataNetRec _amodem_rmnets[MAX_DATA_CONTEXTS];

static const char*
format_inet_addr(ADataType type, AInetAddr addr, int with_mask, char *out, size_t len)
{
char buf[ INET6_ADDRSTRLEN * 2 ]; // include mask

*out = '\0';
switch (type) {
case A_DATA_IP:
if (addr->in.s_addr) {
if (inet_ntop( AF_INET, &addr->in, buf, sizeof buf)) {
snprintf(out, len, (with_mask ? "%s/24" : "%s"), buf);
}
}
break;

case A_DATA_IPV6:
if (addr->in6.s6_addr32[0]) {
if (inet_ntop( AF_INET6, &addr->in6, buf, sizeof buf)) {
snprintf(out, len, (with_mask ? "%s/64" : "%s"), buf);
}
}
break;

default:
break;
}

return out;
}

static void
amodem_init_rmnets()
{
Expand All @@ -816,13 +848,21 @@ amodem_init_rmnets()
ADataNet net = &_amodem_rmnets[j];

net->nd = nd;

int ip = special_addr_ip + 100 + (net - _amodem_rmnets);
net->addr.in.s_addr = htonl(ip);
net->addr.in6.s6_addr32[0] = htonl(0x20010200);
net->addr.in6.s6_addr32[1] = htonl(j);
net->addr.in6.s6_addr32[3] = net->addr.in.s_addr;

net->gw.in.s_addr = htonl(alias_addr_ip);
memcpy(&net->gw.in6, &net->addr.in6, sizeof net->addr.in6);
net->gw.in6.s6_addr32[3] = net->gw.in.s_addr;

for ( k = 0; k < NUM_DNS_PER_RMNET && k < dns_addr_count; k++ ) {
ip = dns_addr[k];
net->dns[k].in.s_addr = htonl(ip);
memcpy(&net->dns[k].in6, &net->addr.in6, sizeof net->addr.in6);
net->dns[k].in6.s6_addr32[3] = net->dns[k].in.s_addr;
}

/* Data connections are down by default. */
Expand Down Expand Up @@ -3220,11 +3260,13 @@ handleDefinePDPContext( const char* cmd, AModem modem )
cmd += 9;
if (cmd[0] == '?') {
/* +CGDCONT=? is used to query the ranges of supported PDP Contexts.
* We only really support IP ones in the emulator, so don't try to
* We only really support IP and IPv6 in the emulator, so don't try to
* fake PPP ones.
*/
amodem_begin_line( modem );
amodem_add_line( modem, "+CGDCONT: (1-%d),\"IP\",,,(0-2),(0-4)",
amodem_add_line( modem, "+CGDCONT: (1-%d),\"IP\",,,(0-2),(0-4)\r\n",
MAX_DATA_CONTEXTS );
amodem_add_line( modem, "+CGDCONT: (1-%d),\"IPV6\",,,(0-2),(0-4)\r\n",
MAX_DATA_CONTEXTS );
amodem_end_line_reply( modem );
return;
Expand All @@ -3235,7 +3277,7 @@ handleDefinePDPContext( const char* cmd, AModem modem )
ADataContext data;
ADataType type;
char apn[A_DATA_APN_SIZE];
char addr[INET_ADDRSTRLEN];
char addr[INET6_ADDRSTRLEN];
const char* p;
int len;

Expand Down Expand Up @@ -3270,6 +3312,9 @@ handleDefinePDPContext( const char* cmd, AModem modem )
if ( !memcmp( cmd, ",\"IP\"", 5 ) ) {
type = A_DATA_IP;
cmd += 5;
} else if ( !memcmp( cmd, ",\"IPV6\"", 7 ) ) {
type = A_DATA_IPV6;
cmd += 7;
} else
goto BadCommand;

Expand Down Expand Up @@ -3313,8 +3358,10 @@ handleDefinePDPContext( const char* cmd, AModem modem )
data->active = 0;
data->type = type;
strcpy( data->apn, apn );
if (inet_pton( AF_INET, addr, &data->addr.in.s_addr) <= 0) {
data->addr.in.s_addr = 0;
if (!addr[0] ||
(type == A_DATA_IP) && (inet_pton( AF_INET, addr, &data->addr.in) <= 0) ||
(type == A_DATA_IPV6) && (inet_pton( AF_INET6, addr, &data->addr.in6) <= 0)) {
memset(&data->addr, 0, sizeof data->addr);
}

amodem_reply( modem, "OK" );
Expand All @@ -3327,26 +3374,23 @@ handleDefinePDPContext( const char* cmd, AModem modem )
static void
handleQueryPDPContext( const char* cmd, AModem modem )
{
static const char* type_names[] = {"IP", "PPP", "IPV6"};

int nn;
amodem_begin_line(modem);
for (nn = 0; nn < MAX_DATA_CONTEXTS; nn++) {
ADataContext data = modem->data_contexts + nn;
char addr[INET_ADDRSTRLEN];
char addr[INET6_ADDRSTRLEN];

if (data->id <= 0)
continue;

/* The read command returns current settings for each defined context. */
if (data->addr.in.s_addr) {
inet_ntop( AF_INET, &data->addr.in, addr, sizeof addr);
} else {
addr[0] = '\0';
}
amodem_add_line( modem, "+CGDCONT: %d,\"%s\",\"%s\",\"%s\",0,0\r\n",
data->id,
data->type == A_DATA_IP ? "IP" : "PPP",
type_names[data->type],
data->apn,
addr );
format_inet_addr(data->type, &data->addr, 0, addr, sizeof addr) );
}
amodem_end_line_reply(modem);
}
Expand Down Expand Up @@ -3412,23 +3456,24 @@ handleListPDPDynamicProp( const char* cmd, AModem modem )
++entries;

ADataNet net = context->net;
char addr[INET_ADDRSTRLEN];
char addr[INET6_ADDRSTRLEN * 2];

/* This is a dirty hack for passing kernel netif num to rild. */
const char* bearer_id = net->nd->name + strlen("rmnet.");
amodem_add_line( modem, "+CGCONTRDP: %d,%s,\"%s\"",
context->id, bearer_id, context->apn );

inet_ntop( AF_INET, &net->addr.in, addr, sizeof addr);
amodem_add_line( modem, ",\"%s/24\"", addr );
inet_ntop( AF_INET, &net->gw.in, addr, sizeof addr);
amodem_add_line( modem, ",\"%s\"", addr );
amodem_add_line( modem, ",\"%s\"",
format_inet_addr(context->type, &net->addr, 1, addr, sizeof addr) );
amodem_add_line( modem, ",\"%s\"",
format_inet_addr(context->type, &net->gw, 0, addr, sizeof addr) );

for ( j = 0; j < NUM_DNS_PER_RMNET; j++ ) {
if (!net->dns[j].in.s_addr) {
break;
}
inet_ntop( AF_INET, &net->dns[j].in, addr, sizeof addr);
amodem_add_line( modem, ",\"%s\"", addr );
amodem_add_line( modem, ",\"%s\"",
format_inet_addr(context->type, &net->dns[j], 0, addr, sizeof addr) );
}

amodem_add_line( modem, "\r\n" );
Expand Down

0 comments on commit 067c08f

Please sign in to comment.