summaryrefslogtreecommitdiffstats
path: root/reference-ril
diff options
context:
space:
mode:
authorBjoern Johansson <bjoernj@google.com>2017-03-22 14:54:00 -0700
committerRoman Kiryanov <rkir@google.com>2018-03-07 15:09:11 -0800
commite1ac3f2ad6a85ee2584a8f015e140af4d158dbf6 (patch)
treea7c288ad28bbebea8054864fa6bec6fedf4824a0 /reference-ril
parentb67d8eb090caca72d1c1f0e7a726b6f13bfaa4d9 (diff)
downloadandroid_hardware_ril-e1ac3f2ad6a85ee2584a8f015e140af4d158dbf6.tar.gz
android_hardware_ril-e1ac3f2ad6a85ee2584a8f015e140af4d158dbf6.tar.bz2
android_hardware_ril-e1ac3f2ad6a85ee2584a8f015e140af4d158dbf6.zip
Enable/disable radio interface on setup/deactivate
When a RIL request to setup or deactivate data calls the radio interface would previously be left up. This caused some problems for IPv6 when switching between WiFi and radio. When WiFi was disable the radio interface would not send a router solicitation and so the IPv6 router table would not be populated with a default gateway. Disabling and enabling the interface solves this since enabling the interface triggers the router solicitation. Additionally this also makes networking unavailable when radio data is turned off as one might expect. Bug: 72886046 Test: manual, build and ran the emulator (steps from CTS tests) Change-Id: I658ebd8ea6e691a6ffb829e38e1ebbec67002645 (cherry picked from commit 9d552844e9936d03cc5a8856040fca18a2d2f5ac) (cherry picked from commit 857f2d522c5163d8bbcf4ba5c9394d043fbc5b82) Signed-off-by: Roman Kiryanov <rkir@google.com>
Diffstat (limited to 'reference-ril')
-rw-r--r--reference-ril/reference-ril.c93
1 files changed, 81 insertions, 12 deletions
diff --git a/reference-ril/reference-ril.c b/reference-ril/reference-ril.c
index 1ba2508..1a1eb9b 100644
--- a/reference-ril/reference-ril.c
+++ b/reference-ril/reference-ril.c
@@ -38,6 +38,10 @@
#include <sys/system_properties.h>
#include <termios.h>
#include <qemu_pipe.h>
+#include <sys/wait.h>
+#include <stdbool.h>
+#include <net/if.h>
+#include <netinet/in.h>
#include "ril.h"
@@ -357,6 +361,55 @@ static int parseSimResponseLine(char* line, RIL_SIM_IO_Response* response) {
return 0;
}
+enum InterfaceState {
+ kInterfaceUp,
+ kInterfaceDown,
+};
+
+static RIL_Errno setInterfaceState(const char* interfaceName,
+ enum InterfaceState state) {
+ struct ifreq request;
+ int status = 0;
+ int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (sock == -1) {
+ RLOGE("Failed to open interface socket: %s (%d)",
+ strerror(errno), errno);
+ return RIL_E_GENERIC_FAILURE;
+ }
+
+ memset(&request, 0, sizeof(request));
+ strncpy(request.ifr_name, interfaceName, sizeof(request.ifr_name));
+ request.ifr_name[sizeof(request.ifr_name) - 1] = '\0';
+ status = ioctl(sock, SIOCGIFFLAGS, &request);
+ if (status != 0) {
+ RLOGE("Failed to get interface flags for %s: %s (%d)",
+ interfaceName, strerror(errno), errno);
+ close(sock);
+ return RIL_E_RADIO_NOT_AVAILABLE;
+ }
+
+ bool isUp = (request.ifr_flags & IFF_UP);
+ if ((state == kInterfaceUp && isUp) || (state == kInterfaceDown && !isUp)) {
+ // Interface already in desired state
+ close(sock);
+ return RIL_E_SUCCESS;
+ }
+
+ // Simply toggle the flag since we know it's the opposite of what we want
+ request.ifr_flags ^= IFF_UP;
+
+ status = ioctl(sock, SIOCSIFFLAGS, &request);
+ if (status != 0) {
+ RLOGE("Failed to set interface flags for %s: %s (%d)",
+ interfaceName, strerror(errno), errno);
+ close(sock);
+ return RIL_E_GENERIC_FAILURE;
+ }
+
+ close(sock);
+ return RIL_E_SUCCESS;
+}
+
/** do post-AT+CFUN=1 initialization */
static void onRadioPowerOn()
{
@@ -511,13 +564,18 @@ static void requestCallSelection(
RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}
-static bool hasWifi()
+static bool hasWifiCapability()
{
char propValue[PROP_VALUE_MAX];
return __system_property_get("ro.kernel.qemu.wifi", propValue) != 0 &&
strcmp("1", propValue) == 0;
}
+static const char* getRadioInterfaceName(bool hasWifi)
+{
+ return hasWifi ? PPP_TTY_PATH_RADIO0 : PPP_TTY_PATH_ETH0;
+}
+
static void requestOrSendDataCallList(RIL_Token *t)
{
ATResponse *p_response;
@@ -526,7 +584,8 @@ static void requestOrSendDataCallList(RIL_Token *t)
int n = 0;
char *out;
char propValue[PROP_VALUE_MAX];
- bool has_wifi = hasWifi();
+ bool hasWifi = hasWifiCapability();
+ const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
err = at_send_command_multiline ("AT+CGACT?", "+CGACT:", &p_response);
if (err != 0 || p_response->success == 0) {
@@ -632,15 +691,9 @@ static void requestOrSendDataCallList(RIL_Token *t)
if (err < 0)
goto error;
- if (has_wifi) {
- int ifname_size = strlen(PPP_TTY_PATH_RADIO0) + 1;
- responses[i].ifname = alloca(ifname_size);
- strlcpy(responses[i].ifname, PPP_TTY_PATH_RADIO0, ifname_size);
- } else {
- int ifname_size = strlen(PPP_TTY_PATH_ETH0) + 1;
- responses[i].ifname = alloca(ifname_size);
- strlcpy(responses[i].ifname, PPP_TTY_PATH_ETH0, ifname_size);
- }
+ int ifname_size = strlen(radioInterfaceName) + 1;
+ responses[i].ifname = alloca(ifname_size);
+ strlcpy(responses[i].ifname, radioInterfaceName, ifname_size);
err = at_tok_nextstr(&line, &out);
if (err < 0)
@@ -687,7 +740,7 @@ static void requestOrSendDataCallList(RIL_Token *t)
/* There is only one gateway in the emulator. If WiFi is
* configured the interface visible to RIL will be behind a NAT
* where the gateway is different. */
- responses[i].gateways = has_wifi ? "192.168.200.1" : "10.0.2.2";
+ responses[i].gateways = hasWifi ? "192.168.200.1" : "10.0.2.2";
responses[i].mtu = DEFAULT_MTU;
}
else {
@@ -1951,6 +2004,11 @@ static void requestSetupDataCall(void *data, size_t datalen, RIL_Token t)
if (qmistatus < 0) goto error;
} else {
+ bool hasWifi = hasWifiCapability();
+ const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
+ if (setInterfaceState(radioInterfaceName, kInterfaceUp) != RIL_E_SUCCESS) {
+ goto error;
+ }
if (datalen > 6 * sizeof(char *)) {
pdp_type = ((const char **)data)[6];
@@ -1994,6 +2052,14 @@ error:
}
+static void requestDeactivateDataCall(RIL_Token t)
+{
+ bool hasWifi = hasWifiCapability();
+ const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
+ RIL_Errno rilErrno = setInterfaceState(radioInterfaceName, kInterfaceDown);
+ RIL_onRequestComplete(t, rilErrno, NULL, 0);
+}
+
static void requestSMSAcknowledge(void *data, size_t datalen __unused, RIL_Token t)
{
int ackSuccess;
@@ -2441,6 +2507,9 @@ onRequest (int request, void *data, size_t datalen, RIL_Token t)
case RIL_REQUEST_SETUP_DATA_CALL:
requestSetupDataCall(data, datalen, t);
break;
+ case RIL_REQUEST_DEACTIVATE_DATA_CALL:
+ requestDeactivateDataCall(t);
+ break;
case RIL_REQUEST_SMS_ACKNOWLEDGE:
requestSMSAcknowledge(data, datalen, t);
break;