@@ -1028,203 +1028,6 @@ int qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
return device->ops->shutdown(device, func, user_data, destroy);
}
-static bool get_device_file_name(struct qmi_device *device,
- char *file_name, int size)
-{
- pid_t pid;
- char temp[100];
- ssize_t result;
- int fd = l_io_get_fd(device->io);
-
- if (size <= 0)
- return false;
-
- pid = getpid();
-
- snprintf(temp, 100, "/proc/%d/fd/%d", (int) pid, fd);
- temp[99] = 0;
-
- result = readlink(temp, file_name, size - 1);
-
- if (result == -1 || result >= size - 1) {
- DBG("Error %d in readlink", errno);
- return false;
- }
-
- file_name[result] = 0;
-
- return true;
-}
-
-static char *get_first_dir_in_directory(char *dir_path)
-{
- DIR *dir;
- struct dirent *dir_entry;
- char *dir_name = NULL;
-
- dir = opendir(dir_path);
-
- if (!dir)
- return NULL;
-
- dir_entry = readdir(dir);
-
- while ((dir_entry != NULL)) {
- if (dir_entry->d_type == DT_DIR &&
- strcmp(dir_entry->d_name, ".") != 0 &&
- strcmp(dir_entry->d_name, "..") != 0) {
- dir_name = l_strdup(dir_entry->d_name);
- break;
- }
-
- dir_entry = readdir(dir);
- }
-
- closedir(dir);
- return dir_name;
-}
-
-static char *get_device_interface(struct qmi_device *device)
-{
- char * const driver_names[] = { "usbmisc", "usb" };
- unsigned int i;
- char file_path[PATH_MAX];
- const char *file_name;
- char *interface = NULL;
-
- if (!get_device_file_name(device, file_path, sizeof(file_path)))
- return NULL;
-
- file_name = l_basename(file_path);
-
- for (i = 0; i < L_ARRAY_SIZE(driver_names) && !interface; i++) {
- char *sysfs_path;
-
- sysfs_path = l_strdup_printf("/sys/class/%s/%s/device/net/",
- driver_names[i], file_name);
- interface = get_first_dir_in_directory(sysfs_path);
- l_free(sysfs_path);
- }
-
- return interface;
-}
-
-enum qmi_device_expected_data_format qmi_device_get_expected_data_format(
- struct qmi_device *device)
-{
- char *sysfs_path = NULL;
- char *interface = NULL;
- int fd = -1;
- char value;
- enum qmi_device_expected_data_format expected =
- QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN;
-
- if (!device)
- goto done;
-
- interface = get_device_interface(device);
-
- if (!interface) {
- DBG("Error while getting interface name");
- goto done;
- }
-
- /* Build sysfs file path and open it */
- sysfs_path = l_strdup_printf("/sys/class/net/%s/qmi/raw_ip", interface);
-
- fd = open(sysfs_path, O_RDONLY);
- if (fd < 0) {
- /* maybe not supported by kernel */
- DBG("Error %d in open(%s)", errno, sysfs_path);
- goto done;
- }
-
- if (read(fd, &value, 1) != 1) {
- DBG("Error %d in read(%s)", errno, sysfs_path);
- goto done;
- }
-
- if (value == 'Y')
- expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP;
- else if (value == 'N')
- expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3;
- else
- DBG("Unexpected sysfs file contents");
-
-done:
- if (fd >= 0)
- close(fd);
-
- if (sysfs_path)
- l_free(sysfs_path);
-
- if (interface)
- l_free(interface);
-
- return expected;
-}
-
-bool qmi_device_set_expected_data_format(struct qmi_device *device,
- enum qmi_device_expected_data_format format)
-{
- bool res = false;
- char *sysfs_path = NULL;
- char *interface = NULL;
- int fd = -1;
- char value;
-
- if (!device)
- goto done;
-
- switch (format) {
- case QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3:
- value = 'N';
- break;
- case QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP:
- value = 'Y';
- break;
- default:
- DBG("Unhandled format: %d", (int) format);
- goto done;
- }
-
- interface = get_device_interface(device);
-
- if (!interface) {
- DBG("Error while getting interface name");
- goto done;
- }
-
- /* Build sysfs file path and open it */
- sysfs_path = l_strdup_printf("/sys/class/net/%s/qmi/raw_ip", interface);
-
- fd = open(sysfs_path, O_WRONLY);
- if (fd < 0) {
- /* maybe not supported by kernel */
- DBG("Error %d in open(%s)", errno, sysfs_path);
- goto done;
- }
-
- if (write(fd, &value, 1) != 1) {
- DBG("Error %d in write(%s)", errno, sysfs_path);
- goto done;
- }
-
- res = true;
-
-done:
- if (fd >= 0)
- close(fd);
-
- if (sysfs_path)
- l_free(sysfs_path);
-
- if (interface)
- l_free(interface);
-
- return res;
-}
-
static int qmi_device_qmux_write(struct qmi_device *device,
struct qmi_request *req)
{
@@ -41,12 +41,6 @@
#define QMI_SERVICE_RMS 225 /* Remote management service */
#define QMI_SERVICE_OMA 226 /* OMA device management service */
-enum qmi_device_expected_data_format {
- QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN,
- QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3,
- QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP,
-};
-
enum qmi_data_endpoint_type {
QMI_DATA_ENDPOINT_TYPE_UNKNOWN = 0x00,
QMI_DATA_ENDPOINT_TYPE_HSIC = 0x01,
@@ -89,11 +83,6 @@ int qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
int qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
void *user_data, qmi_destroy_func_t destroy);
-enum qmi_device_expected_data_format qmi_device_get_expected_data_format(
- struct qmi_device *device);
-bool qmi_device_set_expected_data_format(struct qmi_device *device,
- enum qmi_device_expected_data_format format);
-
struct qmi_qrtr_node *qmi_qrtr_node_new(uint32_t node);
void qmi_qrtr_node_free(struct qmi_qrtr_node *node);
void qmi_qrtr_node_set_debug(struct qmi_qrtr_node *node,
@@ -76,12 +76,13 @@ struct gobi_data {
unsigned long features;
unsigned int discover_attempts;
uint8_t oper_mode;
- bool using_mux;
- bool using_qmi_wwan_q;
int main_net_ifindex;
char main_net_name[IFNAMSIZ];
uint32_t max_aggregation_size;
uint32_t set_powered_id;
+ bool using_mux : 1;
+ bool using_qmi_wwan : 1;
+ bool using_qmi_wwan_q : 1;
};
static void gobi_debug(const char *str, void *user_data)
@@ -134,6 +135,8 @@ static int gobi_probe(struct ofono_modem *modem)
if (!strcmp(if_driver, "qmi_wwan_q"))
data->using_qmi_wwan_q = true;
+ else if (!strcmp(if_driver, "qmi_wwan"))
+ data->using_qmi_wwan = true;
data->main_net_ifindex =
ofono_modem_get_integer(modem, "NetworkInterfaceIndex");
@@ -332,12 +335,49 @@ error:
shutdown_device(modem);
}
+static void setup_qmi_wwan(const char *interface, uint32_t llproto)
+{
+ char raw_ip;
+ char new_raw_ip;
+
+ if (l_sysctl_get_char(&raw_ip, "/sys/class/net/%s/qmi/raw_ip",
+ interface) < 0) {
+ DBG("Couldn't query raw_ip setting");
+ return;
+ }
+
+ if (raw_ip != 'Y' && raw_ip != 'N') {
+ DBG("Unexpected value: %c", raw_ip);
+ return;
+ }
+
+ switch (llproto) {
+ case QMI_WDA_DATA_LINK_PROTOCOL_802_3:
+ new_raw_ip = 'N';
+ break;
+ case QMI_WDA_DATA_LINK_PROTOCOL_RAW_IP:
+ new_raw_ip = 'Y';
+ break;
+ default:
+ DBG("Unknown WDA Link Protocol");
+ return;
+ }
+
+ DBG("raw_ip: %c, want: %c", raw_ip, new_raw_ip);
+
+ if (raw_ip == new_raw_ip)
+ return;
+
+ if (l_sysctl_set_char(new_raw_ip, "/sys/class/net/%s/qmi/raw_ip",
+ interface) < 0)
+ DBG("Fail to set raw_ip to %c", new_raw_ip);
+}
+
static void get_data_format_cb(struct qmi_result *result, void *user_data)
{
struct ofono_modem *modem = user_data;
struct gobi_data *data = ofono_modem_get_data(modem);
uint32_t llproto;
- enum qmi_device_expected_data_format expected_llproto;
DBG("");
@@ -347,24 +387,11 @@ static void get_data_format_cb(struct qmi_result *result, void *user_data)
if (!qmi_result_get_uint32(result, QMI_WDA_LL_PROTOCOL, &llproto))
goto done;
- expected_llproto = qmi_device_get_expected_data_format(data->device);
+ if (data->using_qmi_wwan) {
+ const char *interface =
+ ofono_modem_get_string(modem, "NetworkInterface");
- if ((llproto == QMI_WDA_DATA_LINK_PROTOCOL_802_3) &&
- (expected_llproto ==
- QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP)) {
- if (!qmi_device_set_expected_data_format(data->device,
- QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3))
- DBG("Fail to set expected data to 802.3");
- else
- DBG("expected data set to 802.3");
- } else if ((llproto == QMI_WDA_DATA_LINK_PROTOCOL_RAW_IP) &&
- (expected_llproto ==
- QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3)) {
- if (!qmi_device_set_expected_data_format(data->device,
- QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP))
- DBG("Fail to set expected data to raw-ip");
- else
- DBG("expected data set to raw-ip");
+ setup_qmi_wwan(interface, llproto);
}
done: