1#!/bin/sh
2
3#
4# Copyright (C) 2012 The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#      http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19# Set the APN to be used when making connections on a cellular service.
20
21PROGRAM=$(basename $0)
22FLAGS_HELP="Usage:
23
24  ${PROGRAM}
25
26or
27
28  ${PROGRAM} [-n <network_id>] [-u <username] [-p <password] <apn>
29
30or
31
32  ${PROGRAM} -c
33"
34
35. /usr/share/misc/shflags
36
37FLIMFLAM=org.chromium.flimflam
38IMANAGER=${FLIMFLAM}.Manager
39ISERVICE=${FLIMFLAM}.Service
40APN_PROPERTY=Cellular.APN
41LAST_GOOD_APN_PROPERTY=Cellular.LastGoodAPN
42
43SET_APN_HELPER=$(ls /usr/lib*/shill/shims/set-apn-helper | head -1)
44if [ -z "$SET_APN_HELPER" ] ; then
45  echo "set-apn-helper script was not found!"
46  exit 1
47fi
48
49usage() {
50  echo "$*"
51  echo
52  flags_help
53  exit 1
54}
55
56dbus() {
57  local object="$1"
58  local method="$2"
59  shift 2
60
61  dbus-send --system --print-reply --fixed --dest="${FLIMFLAM}" \
62    "${object}" "${method}" "$@"
63}
64
65get_apn_info() {
66  local service="$1"
67  local property="$2"
68
69  dbus "${service}" "${ISERVICE}.GetProperties" 2>/dev/null \
70    | sed -n "/${property}/s/.*\///p"
71}
72
73display_apn() {
74  local service="$1"
75  local apn="$(get_apn_info ${service} ${LAST_GOOD_APN_PROPERTY})"
76
77  if [ -n "${apn}" ]; then
78    echo "Last good APN: " ${apn}
79    exit 0
80  fi
81
82  apn="$(get_apn_info ${service} ${APN_PROPERTY})"
83  if [ -n "${apn}" ]; then
84    echo "User specified APN: " ${apn}
85    exit 0
86  fi
87
88  echo "No APN."
89  exit 0
90}
91
92set_apn() {
93  local service="$1"
94  local apn="$2"
95  local network_id="$3"
96  local username="$4"
97  local password="$5"
98  local args="apn,${apn},network_id,${network_id}"
99
100  if [ -n "${username}" ]; then
101    args="${args},username,${username}"
102  fi
103
104  if [ -n "${password}" ]; then
105    args="${args},password,${password}"
106  fi
107
108  echo "Setting APN \"${apn}\" for network ID ${network_id} for service ${service}"
109  ${SET_APN_HELPER} "${service}" "${APN_PROPERTY}" "${args}"
110}
111
112clear_apn() {
113  local service="$1"
114
115  echo "Clearing APN for service ${service}"
116  dbus "${service}" "${ISERVICE}.ClearProperty" "string:${APN_PROPERTY}"
117}
118
119get_services() {
120  dbus / "${IMANAGER}.GetProperties" 2>/dev/null \
121    | sed -n "/\/Services\//{s/.* //p}"
122}
123
124get_service_property() {
125  local service="$1"
126  local property="$2"
127
128  dbus "${service}" "${ISERVICE}.GetProperties" 2>/dev/null \
129    | sed -n "/\/${property}/{s/.* //p}"
130}
131
132get_first_cellular_service() {
133  local service
134  local service_type
135
136  for service in $(get_services); do
137    service_type="$(get_service_property ${service} Type)"
138    if [ "${service_type}" = "cellular" ]; then
139      echo "${service}"
140      break
141    fi
142  done
143}
144
145get_cellular_service_network_id() {
146  local service="$1"
147  get_service_property "${service}" "Cellular.ServingOperator\/[0-9]\/code"
148}
149
150service="$(get_first_cellular_service)"
151if [ -z "${service}" ]; then
152  echo "No cellular service exists."
153  exit 1
154fi
155
156if [ $# -lt 1 ]; then
157  display_apn "${service}"
158fi
159
160DEFINE_string 'network_id' "" 'network ID (MCCMNC) of the operator with which the APN should be used' 'n'
161DEFINE_string 'username' "" 'username to be used with the APN' 'u'
162DEFINE_string 'password' "" 'password to be used with the APN' 'p'
163DEFINE_boolean 'clear' false 'clear any APN that has been previously set' 'c'
164FLAGS "$@" || exit 1
165eval set -- "${FLAGS_ARGV}"
166
167network_id="${FLAGS_network_id}"
168if [ -z "${FLAGS_network_id}" ]; then
169  network_id="$(get_cellular_service_network_id ${service})"
170  if [ -z "${network_id}" ]; then
171    echo "Cannot determine network ID. Use the -n flag to specify it."
172    exit 1
173  fi
174fi
175
176if [ "${FLAGS_clear}" -ne 0 ]; then
177  if [ $# -lt 1 ]; then
178    usage "The APN must be specified."
179  elif [ $# -gt 1 ]; then
180    usage "Too many arguments."
181  fi
182  set_apn "${service}" "$1" "${network_id}" "${FLAGS_username}" "${FLAGS_password}"
183else
184  if [ $# -ne 0 ]; then
185    usage "Too many arguments."
186  fi
187  clear_apn "${service}"
188fi
189