bearer-qmi: support binding to data port
Allow plugins to specify a QmiSioPort value to bind to. This is used e.g. in the RPMSG+BAM-DMUX setup in order to allow any RPMSG port to control all the available net ports.
This commit is contained in:
@@ -410,12 +410,14 @@ typedef enum {
|
|||||||
CONNECT_STEP_IPV4,
|
CONNECT_STEP_IPV4,
|
||||||
CONNECT_STEP_WDS_CLIENT_IPV4,
|
CONNECT_STEP_WDS_CLIENT_IPV4,
|
||||||
CONNECT_STEP_IP_FAMILY_IPV4,
|
CONNECT_STEP_IP_FAMILY_IPV4,
|
||||||
|
CONNECT_STEP_BIND_DATA_PORT_IPV4,
|
||||||
CONNECT_STEP_ENABLE_INDICATIONS_IPV4,
|
CONNECT_STEP_ENABLE_INDICATIONS_IPV4,
|
||||||
CONNECT_STEP_START_NETWORK_IPV4,
|
CONNECT_STEP_START_NETWORK_IPV4,
|
||||||
CONNECT_STEP_GET_CURRENT_SETTINGS_IPV4,
|
CONNECT_STEP_GET_CURRENT_SETTINGS_IPV4,
|
||||||
CONNECT_STEP_IPV6,
|
CONNECT_STEP_IPV6,
|
||||||
CONNECT_STEP_WDS_CLIENT_IPV6,
|
CONNECT_STEP_WDS_CLIENT_IPV6,
|
||||||
CONNECT_STEP_IP_FAMILY_IPV6,
|
CONNECT_STEP_IP_FAMILY_IPV6,
|
||||||
|
CONNECT_STEP_BIND_DATA_PORT_IPV6,
|
||||||
CONNECT_STEP_ENABLE_INDICATIONS_IPV6,
|
CONNECT_STEP_ENABLE_INDICATIONS_IPV6,
|
||||||
CONNECT_STEP_START_NETWORK_IPV6,
|
CONNECT_STEP_START_NETWORK_IPV6,
|
||||||
CONNECT_STEP_GET_CURRENT_SETTINGS_IPV6,
|
CONNECT_STEP_GET_CURRENT_SETTINGS_IPV6,
|
||||||
@@ -427,6 +429,7 @@ typedef struct {
|
|||||||
ConnectStep step;
|
ConnectStep step;
|
||||||
MMPort *data;
|
MMPort *data;
|
||||||
MMPortQmi *qmi;
|
MMPortQmi *qmi;
|
||||||
|
QmiSioPort sio_port;
|
||||||
gboolean explicit_qmi_open;
|
gboolean explicit_qmi_open;
|
||||||
gchar *user;
|
gchar *user;
|
||||||
gchar *password;
|
gchar *password;
|
||||||
@@ -988,6 +991,32 @@ get_current_settings (GTask *task, QmiClientWds *client)
|
|||||||
qmi_message_wds_get_current_settings_input_unref (input);
|
qmi_message_wds_get_current_settings_input_unref (input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bind_data_port_ready (QmiClientWds *client,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
ConnectContext *ctx;
|
||||||
|
GError *error = NULL;
|
||||||
|
g_autoptr(QmiMessageWdsBindDataPortOutput) output = NULL;
|
||||||
|
|
||||||
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
g_assert (ctx->running_ipv4 || ctx->running_ipv6);
|
||||||
|
g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
|
||||||
|
|
||||||
|
output = qmi_client_wds_bind_data_port_finish (client, res, &error);
|
||||||
|
if (!output || !qmi_message_wds_bind_data_port_output_get_result (output, &error)) {
|
||||||
|
g_prefix_error (&error, "Couldn't bind data port: ");
|
||||||
|
complete_connect (task, NULL, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep on */
|
||||||
|
ctx->step++;
|
||||||
|
connect_context_step (task);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_ip_family_ready (QmiClientWds *client,
|
set_ip_family_ready (QmiClientWds *client,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
@@ -1401,6 +1430,26 @@ connect_context_step (GTask *task)
|
|||||||
ctx->step++;
|
ctx->step++;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
|
case CONNECT_STEP_BIND_DATA_PORT_IPV4:
|
||||||
|
/* If SIO port given, bind client to it */
|
||||||
|
if (ctx->sio_port != QMI_SIO_PORT_NONE) {
|
||||||
|
g_autoptr(QmiMessageWdsBindDataPortInput) input = NULL;
|
||||||
|
|
||||||
|
mm_obj_dbg (self, "binding to data port: %s", qmi_sio_port_get_string (ctx->sio_port));
|
||||||
|
input = qmi_message_wds_bind_data_port_input_new ();
|
||||||
|
qmi_message_wds_bind_data_port_input_set_data_port (input, ctx->sio_port, NULL);
|
||||||
|
qmi_client_wds_bind_data_port (ctx->client_ipv4,
|
||||||
|
input,
|
||||||
|
10,
|
||||||
|
g_task_get_cancellable (task),
|
||||||
|
(GAsyncReadyCallback)bind_data_port_ready,
|
||||||
|
task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->step++;
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
case CONNECT_STEP_ENABLE_INDICATIONS_IPV4:
|
case CONNECT_STEP_ENABLE_INDICATIONS_IPV4:
|
||||||
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
|
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
|
||||||
ctx->client_ipv4,
|
ctx->client_ipv4,
|
||||||
@@ -1492,6 +1541,26 @@ connect_context_step (GTask *task)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case CONNECT_STEP_BIND_DATA_PORT_IPV6:
|
||||||
|
/* If SIO port given, bind client to it */
|
||||||
|
if (ctx->sio_port != QMI_SIO_PORT_NONE) {
|
||||||
|
g_autoptr(QmiMessageWdsBindDataPortInput) input = NULL;
|
||||||
|
|
||||||
|
mm_obj_dbg (self, "binding to data port: %s", qmi_sio_port_get_string (ctx->sio_port));
|
||||||
|
input = qmi_message_wds_bind_data_port_input_new ();
|
||||||
|
qmi_message_wds_bind_data_port_input_set_data_port (input, ctx->sio_port, NULL);
|
||||||
|
qmi_client_wds_bind_data_port (ctx->client_ipv6,
|
||||||
|
input,
|
||||||
|
10,
|
||||||
|
g_task_get_cancellable (task),
|
||||||
|
(GAsyncReadyCallback)bind_data_port_ready,
|
||||||
|
task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->step++;
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
case CONNECT_STEP_ENABLE_INDICATIONS_IPV6:
|
case CONNECT_STEP_ENABLE_INDICATIONS_IPV6:
|
||||||
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
|
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
|
||||||
ctx->client_ipv6,
|
ctx->client_ipv6,
|
||||||
@@ -1617,6 +1686,7 @@ _connect (MMBaseBearer *_self,
|
|||||||
MMBaseModem *modem = NULL;
|
MMBaseModem *modem = NULL;
|
||||||
MMPort *data = NULL;
|
MMPort *data = NULL;
|
||||||
MMPortQmi *qmi = NULL;
|
MMPortQmi *qmi = NULL;
|
||||||
|
QmiSioPort sio_port = QMI_SIO_PORT_NONE;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
const gchar *apn;
|
const gchar *apn;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
@@ -1642,7 +1712,7 @@ _connect (MMBaseBearer *_self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Each data port has a single QMI port associated */
|
/* Each data port has a single QMI port associated */
|
||||||
qmi = mm_broadband_modem_qmi_get_port_qmi_for_data (MM_BROADBAND_MODEM_QMI (modem), data, &error);
|
qmi = mm_broadband_modem_qmi_get_port_qmi_for_data (MM_BROADBAND_MODEM_QMI (modem), data, &sio_port, &error);
|
||||||
if (!qmi) {
|
if (!qmi) {
|
||||||
g_task_report_error (
|
g_task_report_error (
|
||||||
self,
|
self,
|
||||||
@@ -1689,6 +1759,7 @@ _connect (MMBaseBearer *_self,
|
|||||||
ctx = g_slice_new0 (ConnectContext);
|
ctx = g_slice_new0 (ConnectContext);
|
||||||
ctx->self = g_object_ref (self);
|
ctx->self = g_object_ref (self);
|
||||||
ctx->qmi = g_object_ref (qmi);
|
ctx->qmi = g_object_ref (qmi);
|
||||||
|
ctx->sio_port = sio_port;
|
||||||
ctx->data = g_object_ref (data);
|
ctx->data = g_object_ref (data);
|
||||||
ctx->step = CONNECT_STEP_FIRST;
|
ctx->step = CONNECT_STEP_FIRST;
|
||||||
ctx->ip_method = MM_BEARER_IP_METHOD_UNKNOWN;
|
ctx->ip_method = MM_BEARER_IP_METHOD_UNKNOWN;
|
||||||
|
@@ -213,13 +213,14 @@ mm_broadband_modem_qmi_peek_port_qmi (MMBroadbandModemQmi *self)
|
|||||||
MMPortQmi *
|
MMPortQmi *
|
||||||
mm_broadband_modem_qmi_get_port_qmi_for_data (MMBroadbandModemQmi *self,
|
mm_broadband_modem_qmi_get_port_qmi_for_data (MMBroadbandModemQmi *self,
|
||||||
MMPort *data,
|
MMPort *data,
|
||||||
|
QmiSioPort *out_sio_port,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MMPortQmi *qmi_port;
|
MMPortQmi *qmi_port;
|
||||||
|
|
||||||
g_assert (MM_IS_BROADBAND_MODEM_QMI (self));
|
g_assert (MM_IS_BROADBAND_MODEM_QMI (self));
|
||||||
|
|
||||||
qmi_port = mm_broadband_modem_qmi_peek_port_qmi_for_data (self, data, error);
|
qmi_port = mm_broadband_modem_qmi_peek_port_qmi_for_data (self, data, out_sio_port, error);
|
||||||
return (qmi_port ?
|
return (qmi_port ?
|
||||||
MM_PORT_QMI (g_object_ref (qmi_port)) :
|
MM_PORT_QMI (g_object_ref (qmi_port)) :
|
||||||
NULL);
|
NULL);
|
||||||
@@ -228,6 +229,7 @@ mm_broadband_modem_qmi_get_port_qmi_for_data (MMBroadbandModemQmi *self,
|
|||||||
static MMPortQmi *
|
static MMPortQmi *
|
||||||
peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
||||||
MMPort *data,
|
MMPort *data,
|
||||||
|
QmiSioPort *out_sio_port,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GList *cdc_wdm_qmi_ports;
|
GList *cdc_wdm_qmi_ports;
|
||||||
@@ -282,6 +284,8 @@ peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
|||||||
MM_CORE_ERROR_NOT_FOUND,
|
MM_CORE_ERROR_NOT_FOUND,
|
||||||
"Couldn't find associated QMI port for 'net/%s'",
|
"Couldn't find associated QMI port for 'net/%s'",
|
||||||
mm_port_get_device (data));
|
mm_port_get_device (data));
|
||||||
|
else
|
||||||
|
*out_sio_port = QMI_SIO_PORT_NONE;
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
@@ -289,11 +293,12 @@ peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
|||||||
MMPortQmi *
|
MMPortQmi *
|
||||||
mm_broadband_modem_qmi_peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
mm_broadband_modem_qmi_peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
||||||
MMPort *data,
|
MMPort *data,
|
||||||
|
QmiSioPort *out_sio_port,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
g_assert (MM_BROADBAND_MODEM_QMI_GET_CLASS (self)->peek_port_qmi_for_data);
|
g_assert (MM_BROADBAND_MODEM_QMI_GET_CLASS (self)->peek_port_qmi_for_data);
|
||||||
|
|
||||||
return MM_BROADBAND_MODEM_QMI_GET_CLASS (self)->peek_port_qmi_for_data (self, data, error);
|
return MM_BROADBAND_MODEM_QMI_GET_CLASS (self)->peek_port_qmi_for_data (self, data, out_sio_port, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@@ -39,6 +39,7 @@ struct _MMBroadbandModemQmiClass{
|
|||||||
|
|
||||||
MMPortQmi * (* peek_port_qmi_for_data) (MMBroadbandModemQmi *self,
|
MMPortQmi * (* peek_port_qmi_for_data) (MMBroadbandModemQmi *self,
|
||||||
MMPort *data,
|
MMPort *data,
|
||||||
|
QmiSioPort *out_sio_port,
|
||||||
GError **error);
|
GError **error);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,10 +55,12 @@ MMBroadbandModemQmi *mm_broadband_modem_qmi_new (const gchar *device,
|
|||||||
MMPortQmi *mm_broadband_modem_qmi_peek_port_qmi (MMBroadbandModemQmi *self);
|
MMPortQmi *mm_broadband_modem_qmi_peek_port_qmi (MMBroadbandModemQmi *self);
|
||||||
MMPortQmi *mm_broadband_modem_qmi_peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
MMPortQmi *mm_broadband_modem_qmi_peek_port_qmi_for_data (MMBroadbandModemQmi *self,
|
||||||
MMPort *data,
|
MMPort *data,
|
||||||
|
QmiSioPort *out_sio_port,
|
||||||
GError **error);
|
GError **error);
|
||||||
MMPortQmi *mm_broadband_modem_qmi_get_port_qmi (MMBroadbandModemQmi *self);
|
MMPortQmi *mm_broadband_modem_qmi_get_port_qmi (MMBroadbandModemQmi *self);
|
||||||
MMPortQmi *mm_broadband_modem_qmi_get_port_qmi_for_data (MMBroadbandModemQmi *self,
|
MMPortQmi *mm_broadband_modem_qmi_get_port_qmi_for_data (MMBroadbandModemQmi *self,
|
||||||
MMPort *data,
|
MMPort *data,
|
||||||
|
QmiSioPort *out_sio_port,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
#endif /* MM_BROADBAND_MODEM_QMI_H */
|
#endif /* MM_BROADBAND_MODEM_QMI_H */
|
||||||
|
Reference in New Issue
Block a user