Example #1
0
static void
push_c2dm_client_message_cb (SoupSession *session,
                             SoupMessage *message,
                             gpointer     user_data)
{
   GSimpleAsyncResult *simple = user_data;
   PushC2dmIdentity *identity;
   PushC2dmClient *client = (PushC2dmClient *)session;
   const guint8 *data;
   const gchar *code_str;
   const gchar *registration_id;
   SoupBuffer *buffer;
   gboolean removed = FALSE;
   gsize length;
   guint code;

   ENTRY;

   g_return_if_fail(PUSH_IS_C2DM_CLIENT(client));
   g_return_if_fail(SOUP_IS_MESSAGE(message));
   g_return_if_fail(G_IS_SIMPLE_ASYNC_RESULT(simple));

   buffer = soup_message_body_flatten(message->response_body);
   soup_buffer_get_data(buffer, &data, &length);

   if (message->status_code == SOUP_STATUS_UNAUTHORIZED) {
      g_simple_async_result_set_error(
         simple,
         PUSH_C2DM_CLIENT_ERROR,
         PUSH_C2DM_CLIENT_ERROR_UNAUTHORIZED,
         _("C2DM request unauthorized. Check credentials."));
      GOTO(failure);
   }

   if (!g_utf8_validate((gchar *)data, length, NULL)) {
      g_simple_async_result_set_error(simple,
                                      PUSH_C2DM_CLIENT_ERROR,
                                      PUSH_C2DM_CLIENT_ERROR_UNKNOWN,
                                      _("Received invalid result from C2DM."));
      GOTO(failure);
   }

   if (g_str_has_prefix((gchar *)data, "id=")) {
      g_simple_async_result_set_op_res_gboolean(simple, TRUE);
   } else {
      if (g_str_equal(data, "Error=QuotaExceeded")) {
         code = PUSH_C2DM_CLIENT_ERROR_QUOTA_EXCEEDED;
         code_str = _("Quota exceeded.");
      } else if (g_str_equal(data, "Error=DeviceQuotaExceeded")) {
         code = PUSH_C2DM_CLIENT_ERROR_DEVICE_QUOTA_EXCEEDED;
         code_str = _("Device quota exceeded.");
      } else if (g_str_equal(data, "Error=MissingRegistration")) {
         code = PUSH_C2DM_CLIENT_ERROR_MISSING_REGISTRATION;
         code_str = _("Missing registration.");
         removed = TRUE;
      } else if (g_str_equal(data, "Error=InvalidRegistration")) {
         code = PUSH_C2DM_CLIENT_ERROR_INVALID_REGISTRATION;
         code_str = _("Invalid registration.");
         removed = TRUE;
      } else if (g_str_equal(data, "Error=MismatchSenderId")) {
         code = PUSH_C2DM_CLIENT_ERROR_MISMATCH_SENDER_ID;
         code_str = _("Mismatch sender id.");
      } else if (g_str_equal(data, "Error=NotRegistered")) {
         code = PUSH_C2DM_CLIENT_ERROR_NOT_REGISTERED;
         code_str = _("Not registered.");
         removed = TRUE;
      } else if (g_str_equal(data, "Error=MessageTooBig")) {
         code = PUSH_C2DM_CLIENT_ERROR_MESSAGE_TOO_BIG;
         code_str = _("Message too big.");
      } else if (g_str_equal(data, "Error=MissingCollapseKey")) {
         code = PUSH_C2DM_CLIENT_ERROR_MISSING_COLLAPSE_KEY;
         code_str = _("Missing collapse key.");
      } else {
         code = PUSH_C2DM_CLIENT_ERROR_UNKNOWN;
         code_str = _("An unknown error occurred.");
      }
      g_simple_async_result_set_error(simple,
                                      PUSH_C2DM_CLIENT_ERROR,
                                      code, "%s", code_str);
      if (removed) {
         registration_id = g_object_get_data(G_OBJECT(simple),
                                             "registration-id");
         identity = g_object_new(PUSH_TYPE_C2DM_IDENTITY,
                                 "registration-id", registration_id,
                                 NULL);
         g_signal_emit(client, gSignals[IDENTITY_REMOVED], 0, identity);
         g_object_unref(identity);
      }
   }

failure:
   soup_buffer_free(buffer);
   g_simple_async_result_complete_in_idle(simple);
   g_object_unref(simple);

   EXIT;
}
Example #2
0
/* This function is executed in the main thread, decides the
 * module that's going to be run for a given task, and dispatches
 * the task according to the threading strategy of that module.
 */
static gboolean
dispatch_task_cb (TrackerExtractTask *task)
{
	TrackerModuleThreadAwareness thread_awareness;
	TrackerExtractPrivate *priv;
	GError *error = NULL;
	GModule *module;

#ifdef THREAD_ENABLE_TRACE
	g_debug ("Thread:%p (Main) <-- File:'%s' - Dispatching\n",
	         g_thread_self (),
	         task->file);
#endif /* THREAD_ENABLE_TRACE */

	priv = TRACKER_EXTRACT_GET_PRIVATE (task->extract);

	if (!task->mimetype) {
		error = g_error_new (TRACKER_DBUS_ERROR, 0,
		                     "No mimetype for '%s'",
		                     task->file);
	} else {
		if (!task->mimetype_handlers) {
			/* First iteration for task, get the mimetype handlers */
			task->mimetype_handlers = tracker_extract_module_manager_get_mimetype_handlers (task->mimetype);

			if (!task->mimetype_handlers) {
				error = g_error_new (TRACKER_DBUS_ERROR, 0,
				                     "No mimetype extractor handlers for uri:'%s' and mime:'%s'",
				                     task->file, task->mimetype);
			}
		} else {
			/* Any further iteration, should happen rarely if
			 * most specific handlers know nothing about the file
			 */
			g_message ("Trying next extractor for '%s'", task->file);

			if (!tracker_mimetype_info_iter_next (task->mimetype_handlers)) {
				g_message ("  There's no next extractor");

				error = g_error_new (TRACKER_DBUS_ERROR, 0,
				                     "Could not get any metadata for uri:'%s' and mime:'%s'",
				                     task->file, task->mimetype);
			}
		}
	}

	if (error) {
		g_simple_async_result_set_from_error ((GSimpleAsyncResult *) task->res, error);
		g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res);
		extract_task_free (task);
		g_error_free (error);

		return FALSE;
	}

	task->cur_module = module = tracker_mimetype_info_get_module (task->mimetype_handlers, &task->cur_func, &thread_awareness);

	if (!module || !task->cur_func) {
		g_warning ("Discarding task with no module '%s'", task->file);
		priv->unhandled_count++;
		return FALSE;
	}

	g_mutex_lock (&priv->task_mutex);
	priv->running_tasks = g_list_prepend (priv->running_tasks, task);
	g_mutex_unlock (&priv->task_mutex);

	switch (thread_awareness) {
	case TRACKER_MODULE_NONE:
		/* Error out */
		g_simple_async_result_set_error ((GSimpleAsyncResult *) task->res,
		                                 TRACKER_DBUS_ERROR, 0,
		                                 "Module '%s' initialization failed",
		                                 g_module_name (module));
		g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res);
		extract_task_free (task);
		break;
	case TRACKER_MODULE_MAIN_THREAD:
		/* Dispatch the task right away in this thread */
		g_message ("Dispatching '%s' in main thread", task->file);
		get_metadata (task);
		break;
	case TRACKER_MODULE_SINGLE_THREAD: {
		GAsyncQueue *async_queue;

		async_queue = g_hash_table_lookup (priv->single_thread_extractors, module);

		if (!async_queue) {
			GThread *thread;

			/* No thread created yet for this module, create it
			 * together with the async queue used to pass data to it
			 */
			async_queue = g_async_queue_new ();
			thread = g_thread_try_new ("single",
			                           (GThreadFunc) single_thread_get_metadata,
			                           g_async_queue_ref (async_queue),
			                           &error);
			if (!thread) {
				g_simple_async_result_take_error ((GSimpleAsyncResult *) task->res, error);
				g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res);
				extract_task_free (task);
				return FALSE;
			}

			/* We won't join the thread, so just unref it here */
			g_object_unref (thread);

			g_hash_table_insert (priv->single_thread_extractors, module, async_queue);
		}

		g_async_queue_push (async_queue, task);
		break;
	}
	case TRACKER_MODULE_MULTI_THREAD:
		/* Put task in thread pool */
		g_message ("Dispatching '%s' in thread pool", task->file);
		g_thread_pool_push (priv->thread_pool, task, &error);

		if (error) {
			g_simple_async_result_set_from_error ((GSimpleAsyncResult *) task->res, error);
			g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res);
			extract_task_free (task);
			g_error_free (error);

			return FALSE;
		}

		break;
	}

	return FALSE;
}
static void
huawei_custom_init (MMPortProbe *probe,
                    MMAtSerialPort *port,
                    GCancellable *cancellable,
                    GAsyncReadyCallback callback,
                    gpointer user_data)
{
    MMDevice *device;
    FirstInterfaceContext *fi_ctx;
    HuaweiCustomInitContext *ctx;

    device = mm_port_probe_peek_device (probe);

    /* The primary port (called the "modem" port in the Windows drivers) is
     * always USB interface 0, and we need to detect that interface first for
     * two reasons: (1) to disable unsolicited messages on other ports that
     * may fill up the buffer and crash the device, and (2) to attempt to get
     * the port layout for hints about what the secondary port is (called the
     * "pcui" port in Windows).  Thus we probe USB interface 0 first and defer
     * probing other interfaces until we've got if0, at which point we allow
     * the other ports to be probed too.
     */
    fi_ctx = g_object_get_data (G_OBJECT (device), TAG_FIRST_INTERFACE_CONTEXT);
    if (!fi_ctx) {
        /* This is the first time we ask for the context. Set it up. */
        fi_ctx = g_slice_new0 (FirstInterfaceContext);
        g_object_set_data_full (G_OBJECT (device),
                                TAG_FIRST_INTERFACE_CONTEXT,
                                fi_ctx,
                                (GDestroyNotify)first_interface_context_free);
        /* The timeout is controlled in the data set in 'device', and therefore
         * it should be safe to assume that the timeout will not get fired after
         * having disposed 'device' */
        fi_ctx->timeout_id = g_timeout_add_seconds (MAX_WAIT_TIME,
                                                    (GSourceFunc)first_interface_missing_timeout_cb,
                                                    device);

        /* By default, we'll ask the Huawei plugin to start probing usbif 0 */
        fi_ctx->first_usbif = 0;

        /* Custom init of the Huawei plugin is to be run only in the first
         * interface. We'll control here whether we did run it already or not. */
        fi_ctx->custom_init_run = FALSE;
    }

    ctx = g_slice_new (HuaweiCustomInitContext);
    ctx->result = g_simple_async_result_new (G_OBJECT (probe),
                                             callback,
                                             user_data,
                                             huawei_custom_init);
    ctx->probe = g_object_ref (probe);
    ctx->port = g_object_ref (port);
    ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
    ctx->curc_done = FALSE;
    ctx->curc_retries = 3;
    ctx->getportmode_done = FALSE;
    ctx->getportmode_retries = 3;

    /* Custom init only to be run in the first interface */
    if (g_udev_device_get_property_as_int (mm_port_probe_peek_port (probe),
                                           "ID_USB_INTERFACE_NUM") != fi_ctx->first_usbif) {

        if (fi_ctx->custom_init_run)
            /* If custom init was run already, we can consider this as successfully run */
            g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        else
            /* Otherwise, we'll need to defer the probing a bit more */
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_RETRY,
                                             "Defer needed");

        huawei_custom_init_context_complete_and_free (ctx);
        return;
    }

    /* We can run custom init in the first interface! clear the timeout as it is no longer needed */
    g_source_remove (fi_ctx->timeout_id);
    fi_ctx->timeout_id = 0;

    huawei_custom_init_step (ctx);
}
static void
at_sequence_parse_response (MMAtSerialPort *port,
                            GString *response,
                            GError *error,
                            AtSequenceContext *ctx)
{
    GVariant *result = NULL;
    GError *result_error = NULL;
    gboolean continue_sequence;
    GSimpleAsyncResult *simple;

    /* Cancelled? */
    if (g_cancellable_is_cancelled (ctx->cancellable)) {
        g_simple_async_result_set_error (ctx->simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_CANCELLED,
                                         "AT sequence was cancelled");
        g_simple_async_result_complete (ctx->simple);
        at_sequence_context_free (ctx);
        return;
    }

    if (!ctx->current->response_processor)
        /* No need to process response, go on to next command */
        continue_sequence = TRUE;
    else {
        const MMBaseModemAtCommand *next = ctx->current + 1;

        /* Response processor will tell us if we need to keep on the sequence */
        continue_sequence = !ctx->current->response_processor (
            ctx->self,
            ctx->response_processor_context,
            ctx->current->command,
            response ? response->str : NULL,
            next->command ? FALSE : TRUE,  /* Last command in sequence? */
            error,
            &result,
            &result_error);
        /* Were we told to abort the sequence? */
        if (result_error) {
            g_assert (result == NULL);
            g_simple_async_result_take_error (ctx->simple, result_error);
            g_simple_async_result_complete (ctx->simple);
            at_sequence_context_free (ctx);
            return;
        }
    }

    if (continue_sequence) {
        g_assert (result == NULL);
        ctx->current++;
        if (ctx->current->command) {
            /* Schedule the next command in the probing group */
            if (ctx->current->allow_cached)
                mm_at_serial_port_queue_command_cached (
                    ctx->port,
                    ctx->current->command,
                    ctx->current->timeout,
                    FALSE,
                    ctx->cancellable,
                    (MMAtSerialResponseFn)at_sequence_parse_response,
                    ctx);
            else
                mm_at_serial_port_queue_command (
                    ctx->port,
                    ctx->current->command,
                    ctx->current->timeout,
                    FALSE,
                    ctx->cancellable,
                    (MMAtSerialResponseFn)at_sequence_parse_response,
                    ctx);
            return;
        }

        /* On last command, end. */
    }

    /* If we got a response, set it as result */
    if (result)
        /* transfer-full */
        ctx->result = result;

    /* Set the whole context as result, in order to pass the response
     * processor context during finish(). We do remove the simple async result
     * from the context as well, so that we control its last unref. */
    simple = ctx->simple;
    ctx->simple = NULL;
    g_simple_async_result_set_op_res_gpointer (
        simple,
        ctx,
        (GDestroyNotify)at_sequence_context_free);

    /* And complete. The whole context is owned by the result, and it will
     * be freed when completed. */
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}
void win_usb_driver_handle_reply_cb(GObject *gobject,
                                    GAsyncResult *read_res,
                                    gpointer user_data)
{
    SpiceWinUsbDriver *self;
    SpiceWinUsbDriverPrivate *priv;

    GInputStream *istream;
    GError *err = NULL;
    gssize bytes;

    g_return_if_fail(SPICE_IS_WIN_USB_DRIVER(user_data));
    self = SPICE_WIN_USB_DRIVER(user_data);
    priv = self->priv;
    istream = G_INPUT_STREAM(gobject);

    bytes = g_input_stream_read_finish(istream, read_res, &err);

    SPICE_DEBUG("Finished reading reply-msg from usbclerk: bytes=%ld "
                "err_exist?=%d", (long)bytes, err!=NULL);

    g_warn_if_fail(g_input_stream_close(istream, NULL, NULL));
    g_clear_object(&istream);

    if (err) {
        g_warning("failed to read reply from usbclerk (%s)", err->message);
        g_simple_async_result_take_error(priv->result, err);
        goto failed_reply;
    }

    if (bytes == 0) {
        g_warning("unexpected EOF from usbclerk");
        g_simple_async_result_set_error(priv->result,
                                        SPICE_WIN_USB_DRIVER_ERROR,
                                        SPICE_WIN_USB_DRIVER_ERROR_FAILED,
                                        "unexpected EOF from usbclerk");
        goto failed_reply;
    }

    if (bytes != sizeof(priv->reply)) {
        g_warning("usbclerk size mismatch: read %d bytes, expected %d (header %d, size in header %d)",
                  bytes, sizeof(priv->reply), sizeof(priv->reply.hdr), priv->reply.hdr.size);
        /* For now just warn, do not fail */
    }

    if (priv->reply.hdr.magic != USB_CLERK_MAGIC) {
        g_warning("usbclerk magic mismatch: mine=0x%04x  server=0x%04x",
                  USB_CLERK_MAGIC, priv->reply.hdr.magic);
        g_simple_async_result_set_error(priv->result,
                                        SPICE_WIN_USB_DRIVER_ERROR,
                                        SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
                                        "usbclerk magic mismatch");
        goto failed_reply;
    }

    if (priv->reply.hdr.version != USB_CLERK_VERSION) {
        g_warning("usbclerk version mismatch: mine=0x%04x  server=0x%04x",
                  USB_CLERK_VERSION, priv->reply.hdr.version);
        g_simple_async_result_set_error(priv->result,
                                        SPICE_WIN_USB_DRIVER_ERROR,
                                        SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
                                        "usbclerk version mismatch");
    }

    if (priv->reply.hdr.type != USB_CLERK_REPLY) {
        g_warning("usbclerk message with unexpected type %d",
                  priv->reply.hdr.type);
        g_simple_async_result_set_error(priv->result,
                                        SPICE_WIN_USB_DRIVER_ERROR,
                                        SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
                                        "usbclerk message with unexpected type");
        goto failed_reply;
    }

    if (priv->reply.hdr.size != bytes) {
        g_warning("usbclerk message size mismatch: read %d bytes  hdr.size=%d",
                  bytes, priv->reply.hdr.size);
        g_simple_async_result_set_error(priv->result,
                                        SPICE_WIN_USB_DRIVER_ERROR,
                                        SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
                                        "usbclerk message with unexpected size");
        goto failed_reply;
    }

 failed_reply:
    g_simple_async_result_complete_in_idle(priv->result);
    g_clear_object(&priv->result);
}
static void
interface_initialization_step (InitializationContext *ctx)
{
    /* Don't run new steps if we're cancelled */
    if (initialization_context_complete_and_free_if_cancelled (ctx))
        return;

    switch (ctx->step) {
    case INITIALIZATION_STEP_FIRST:
        /* Setup quarks if we didn't do it before */
        if (G_UNLIKELY (!support_checked_quark))
            support_checked_quark = (g_quark_from_static_string (
                                         SUPPORT_CHECKED_TAG));
        if (G_UNLIKELY (!supported_quark))
            supported_quark = (g_quark_from_static_string (
                                   SUPPORTED_TAG));

        /* Fall down to next step */
        ctx->step++;

    case INITIALIZATION_STEP_CHECK_SUPPORT:
        if (!GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (ctx->self),
                                                   support_checked_quark))) {
            /* Set the checked flag so that we don't run it again */
            g_object_set_qdata (G_OBJECT (ctx->self),
                                support_checked_quark,
                                GUINT_TO_POINTER (TRUE));
            /* Initially, assume we don't support it */
            g_object_set_qdata (G_OBJECT (ctx->self),
                                supported_quark,
                                GUINT_TO_POINTER (FALSE));

            if (MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (ctx->self)->check_support &&
                MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (ctx->self)->check_support_finish) {
                MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (ctx->self)->check_support (
                    ctx->self,
                    (GAsyncReadyCallback)check_support_ready,
                    ctx);
                return;
            }

            /* If there is no implementation to check support, assume we DON'T
             * support it. */
        }
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZATION_STEP_FAIL_IF_UNSUPPORTED:
        if (!GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (ctx->self),
                                                   supported_quark))) {
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_UNSUPPORTED,
                                             "Messaging not supported");
            initialization_context_complete_and_free (ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZATION_STEP_LOAD_SUPPORTED_STORAGES:
        if (MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (ctx->self)->load_supported_storages &&
            MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (ctx->self)->load_supported_storages_finish) {
            MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (ctx->self)->load_supported_storages (
                ctx->self,
                (GAsyncReadyCallback)load_supported_storages_ready,
                ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZATION_STEP_LAST:
        /* We are done without errors! */

        /* Handle method invocations */
        g_signal_connect (ctx->skeleton,
                          "handle-create",
                          G_CALLBACK (handle_create),
                          ctx->self);
        g_signal_connect (ctx->skeleton,
                          "handle-delete",
                          G_CALLBACK (handle_delete),
                          ctx->self);
        g_signal_connect (ctx->skeleton,
                          "handle-list",
                          G_CALLBACK (handle_list),
                          ctx->self);

        /* Finally, export the new interface */
        mm_gdbus_object_skeleton_set_modem_messaging (MM_GDBUS_OBJECT_SKELETON (ctx->self),
                                                      MM_GDBUS_MODEM_MESSAGING (ctx->skeleton));

        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        initialization_context_complete_and_free (ctx);
        return;
    }

    g_assert_not_reached ();
}
Example #7
0
static void
cockpit_auth_remote_login_async (CockpitAuth *self,
                                 const gchar *application,
                                 const gchar *type,
                                 GHashTable *headers,
                                 const gchar *remote_peer,
                                 GAsyncReadyCallback callback,
                                 gpointer user_data)
{
  GSimpleAsyncResult *task;
  AuthData *ad = NULL;
  GBytes *input = NULL;
  GBytes *auth_bytes = NULL;
  gchar *user = NULL;
  gchar *password = NULL; /* owned by input */

  const gchar *data = NULL;
  const gchar *command;
  const gchar *host;
  const gchar *host_arg;
  gint next_arg = 1;

  const gchar *argv[] = {
      cockpit_ws_ssh_program,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
  };

  task = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                    cockpit_auth_remote_login_async);
  if (g_strcmp0 (type, "basic") == 0)
    {
      input = cockpit_auth_parse_authorization (headers, TRUE);
      data = g_bytes_get_data (input, NULL);

      password = strchr (data, ':');
      if (password != NULL)
        {
          user = g_strndup (data, password - data);
          password++;
          auth_bytes = g_bytes_new_static (password, strlen(password));
        }
    }
  else
    {
      input = cockpit_auth_parse_authorization (headers, FALSE);
      if (input)
        auth_bytes = g_bytes_ref (input);
    }

  if (application && auth_bytes && input)
    {
      command = type_option (SSH_SECTION, "command", cockpit_ws_ssh_program);
      argv[0] = command;

      host = application_parse_host (application);
      if (host)
        {
          host_arg = host;
          if (g_strcmp0 (remote_peer, "127.0.0.1") == 0 ||
              g_strcmp0 (remote_peer, "::1") == 0 ||
              cockpit_conf_bool (SSH_SECTION, "allowUnknown", FALSE))
            {
              argv[next_arg++] = "--prompt-unknown-hostkey";
            }
        }
      else
        {
          argv[next_arg++] = "--ignore-hostkey";
          if (cockpit_conf_string (SSH_SECTION, "host"))
            host_arg = cockpit_conf_string (SSH_SECTION, "host");
          else
            host_arg = "localhost";
        }

      argv[next_arg++] = host_arg;
      argv[next_arg++] = user;
      ad = create_auth_data (self, host_arg, application,
                             SSH_SECTION, remote_peer, command, input);
      start_auth_process (self, ad, auth_bytes, task,
                          cockpit_auth_remote_login_async, argv);
    }
  else
    {
      g_simple_async_result_set_error (task, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED,
                                       "Basic authentication required");
      g_simple_async_result_complete_in_idle (task);
    }

  if (auth_bytes)
    g_bytes_unref (auth_bytes);

  if (input)
    g_bytes_unref (input);

  if (ad)
    auth_data_unref (ad);

  if (user)
    g_free (user);

  g_object_unref (task);
}
Example #8
0
static void
connect_context_step (ConnectContext *ctx)
{
    /* If cancelled, complete */
    if (g_cancellable_is_cancelled (ctx->cancellable)) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_CANCELLED,
                                         "Connection setup operation has been cancelled");
        connect_context_complete_and_free (ctx);
        return;
    }

    switch (ctx->step) {
    case CONNECT_STEP_FIRST:

        g_assert (ctx->ipv4 || ctx->ipv6);

        /* Fall down */
        ctx->step++;

    case CONNECT_STEP_OPEN_QMI_PORT:
        if (!mm_qmi_port_is_open (ctx->qmi)) {
            mm_qmi_port_open (ctx->qmi,
                              TRUE,
                              ctx->cancellable,
                              (GAsyncReadyCallback)qmi_port_open_ready,
                              ctx);
            return;
        }

        /* If already open, just fall down */
        ctx->step++;

    case CONNECT_STEP_IPV4:
        /* If no IPv4 setup needed, jump to IPv6 */
        if (!ctx->ipv4) {
            ctx->step = CONNECT_STEP_IPV6;
            connect_context_step (ctx);
            return;
        }

        /* Start IPv4 setup */
        mm_dbg ("Running IPv4 connection setup");
        ctx->running_ipv4 = TRUE;
        ctx->running_ipv6 = FALSE;
        /* Just fall down */
        ctx->step++;

    case CONNECT_STEP_WDS_CLIENT_IPV4: {
        QmiClient *client;

        client = mm_qmi_port_get_client (ctx->qmi,
                                         QMI_SERVICE_WDS,
                                         MM_QMI_PORT_FLAG_WDS_IPV4);
        if (!client) {
            mm_dbg ("Allocating IPv4-specific WDS client");
            mm_qmi_port_allocate_client (ctx->qmi,
                                         QMI_SERVICE_WDS,
                                         MM_QMI_PORT_FLAG_WDS_IPV4,
                                         ctx->cancellable,
                                         (GAsyncReadyCallback)qmi_port_allocate_client_ready,
                                         ctx);
            return;
        }

        ctx->client_ipv4 = QMI_CLIENT_WDS (client);
        /* Just fall down */
        ctx->step++;
    }

    case CONNECT_STEP_IP_FAMILY_IPV4:
        /* If client is new enough, select IP family */
        if (!ctx->no_ip_family_preference &&
            qmi_client_check_version (QMI_CLIENT (ctx->client_ipv4), 1, 9)) {
            QmiMessageWdsSetIpFamilyInput *input;

            mm_dbg ("Setting default IP family to: IPv4");
            input = qmi_message_wds_set_ip_family_input_new ();
            qmi_message_wds_set_ip_family_input_set_preference (input, QMI_WDS_IP_FAMILY_IPV4, NULL);
            qmi_client_wds_set_ip_family (ctx->client_ipv4,
                                          input,
                                          10,
                                          ctx->cancellable,
                                          (GAsyncReadyCallback)set_ip_family_ready,
                                          ctx);
            qmi_message_wds_set_ip_family_input_unref (input);
            return;
        }

        ctx->default_ip_family_set = FALSE;

        /* Just fall down */
        ctx->step++;

    case CONNECT_STEP_START_NETWORK_IPV4: {
        QmiMessageWdsStartNetworkInput *input;

        mm_dbg ("Starting IPv4 connection...");
        input = build_start_network_input (ctx);
        qmi_client_wds_start_network (ctx->client_ipv4,
                                      input,
                                      45,
                                      ctx->cancellable,
                                      (GAsyncReadyCallback)start_network_ready,
                                      ctx);
        qmi_message_wds_start_network_input_unref (input);
        return;
    }

    case CONNECT_STEP_IPV6:
        /* If no IPv6 setup needed, jump to last */
        if (!ctx->ipv6) {
            ctx->step = CONNECT_STEP_GET_CURRENT_SETTINGS;
            connect_context_step (ctx);
            return;
        }

        /* Start IPv6 setup */
        mm_dbg ("Running IPv6 connection setup");
        ctx->running_ipv4 = FALSE;
        ctx->running_ipv6 = TRUE;
        /* Just fall down */
        ctx->step++;

    case CONNECT_STEP_WDS_CLIENT_IPV6: {
        QmiClient *client;

        client = mm_qmi_port_get_client (ctx->qmi,
                                         QMI_SERVICE_WDS,
                                         MM_QMI_PORT_FLAG_WDS_IPV6);
        if (!client) {
            mm_dbg ("Allocating IPv6-specific WDS client");
            mm_qmi_port_allocate_client (ctx->qmi,
                                         QMI_SERVICE_WDS,
                                         MM_QMI_PORT_FLAG_WDS_IPV6,
                                         ctx->cancellable,
                                         (GAsyncReadyCallback)qmi_port_allocate_client_ready,
                                         ctx);
            return;
        }

        ctx->client_ipv6 = QMI_CLIENT_WDS (client);
        /* Just fall down */
        ctx->step++;
    }

    case CONNECT_STEP_IP_FAMILY_IPV6:

        g_assert (ctx->no_ip_family_preference == FALSE);

        /* If client is new enough, select IP family */
        if (qmi_client_check_version (QMI_CLIENT (ctx->client_ipv6), 1, 9)) {
            QmiMessageWdsSetIpFamilyInput *input;

            mm_dbg ("Setting default IP family to: IPv6");
            input = qmi_message_wds_set_ip_family_input_new ();
            qmi_message_wds_set_ip_family_input_set_preference (input, QMI_WDS_IP_FAMILY_IPV6, NULL);
            qmi_client_wds_set_ip_family (ctx->client_ipv6,
                                          input,
                                          10,
                                          ctx->cancellable,
                                          (GAsyncReadyCallback)set_ip_family_ready,
                                          ctx);
            qmi_message_wds_set_ip_family_input_unref (input);
            return;
        }

        ctx->default_ip_family_set = FALSE;

        /* Just fall down */
        ctx->step++;

    case CONNECT_STEP_START_NETWORK_IPV6: {
        QmiMessageWdsStartNetworkInput *input;

        mm_dbg ("Starting IPv6 connection...");
        input = build_start_network_input (ctx);
        qmi_client_wds_start_network (ctx->client_ipv6,
                                      input,
                                      45,
                                      ctx->cancellable,
                                      (GAsyncReadyCallback)start_network_ready,
                                      ctx);
        qmi_message_wds_start_network_input_unref (input);
        return;
    }

    case CONNECT_STEP_GET_CURRENT_SETTINGS: {
        QmiMessageWdsGetCurrentSettingsInput *input;
        QmiClientWds *client;

        if (ctx->running_ipv4)
            client = ctx->client_ipv4;
        else if (ctx->running_ipv6)
            client = ctx->client_ipv6;
        else
            g_assert_not_reached ();

        mm_dbg ("Getting IP configuration...");
        input = build_get_current_settings_input (ctx);
        qmi_client_wds_get_current_settings (client,
                                             input,
                                             45,
                                             ctx->cancellable,
                                             (GAsyncReadyCallback)get_current_settings_ready,
                                             ctx);
        qmi_message_wds_get_current_settings_input_unref (input);
        return;
    }

    case CONNECT_STEP_LAST:
        /* If one of IPv4 or IPv6 succeeds, we're connected */
        if (ctx->packet_data_handle_ipv4 || ctx->packet_data_handle_ipv6) {
            MMBearerIpConfig *config;
            ConnectResult *result;

            /* Port is connected; update the state */
            mm_port_set_connected (MM_PORT (ctx->data), TRUE);

            /* Keep connection related data */
            g_assert (ctx->self->priv->data == NULL);
            ctx->self->priv->data = g_object_ref (ctx->data);

            g_assert (ctx->self->priv->packet_data_handle_ipv4 == 0);
            g_assert (ctx->self->priv->client_ipv4 == NULL);
            if (ctx->packet_data_handle_ipv4) {
                ctx->self->priv->packet_data_handle_ipv4 = ctx->packet_data_handle_ipv4;
                ctx->self->priv->client_ipv4 = g_object_ref (ctx->client_ipv4);
            }

            g_assert (ctx->self->priv->packet_data_handle_ipv6 == 0);
            g_assert (ctx->self->priv->client_ipv6 == NULL);
            if (ctx->packet_data_handle_ipv6) {
                ctx->self->priv->packet_data_handle_ipv6 = ctx->packet_data_handle_ipv6;
                ctx->self->priv->client_ipv6 = g_object_ref (ctx->client_ipv6);
            }

            /* Build IP config; always DHCP based */
            config = mm_bearer_ip_config_new ();
            mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_DHCP);

            /* Build result */
            result = g_slice_new0 (ConnectResult);
            result->data = g_object_ref (ctx->data);
            if (ctx->packet_data_handle_ipv4)
                result->ipv4_config = g_object_ref (config);
            if (ctx->packet_data_handle_ipv6)
                result->ipv6_config = g_object_ref (config);

            g_object_unref (config);

            /* Set operation result */
            g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                       result,
                                                       (GDestroyNotify)connect_result_free);
        } else {
            GError *error;

            /* No connection, set error. If both set, IPv4 error preferred */
            if (ctx->error_ipv4) {
                error = ctx->error_ipv4;
                ctx->error_ipv4 = NULL;
            } else {
                error = ctx->error_ipv6;
                ctx->error_ipv6 = NULL;
            }

            g_simple_async_result_take_error (ctx->result, error);
        }

        connect_context_complete_and_free (ctx);
        return;
    }
}
Example #9
0
static void
_connect (MMBearer *self,
          GCancellable *cancellable,
          GAsyncReadyCallback callback,
          gpointer user_data)
{
    MMBearerProperties *properties = NULL;
    ConnectContext *ctx;
    MMBaseModem *modem  = NULL;
    MMPort *data;
    MMQmiPort *qmi;
    GError *error = NULL;

    g_object_get (self,
                  MM_BEARER_MODEM, &modem,
                  NULL);
    g_assert (modem);

    /* Grab a data port */
    data = mm_base_modem_get_best_data_port (modem);
    if (!data) {
        g_simple_async_report_error_in_idle (
            G_OBJECT (self),
            callback,
            user_data,
            MM_CORE_ERROR,
            MM_CORE_ERROR_NOT_FOUND,
            "No valid data port found to launch connection");
        g_object_unref (modem);
        return;
    }

    /* Each data port has a single QMI port associated */
    qmi = mm_base_modem_get_port_qmi_for_data (modem, data, &error);
    if (!qmi) {
        g_simple_async_report_take_gerror_in_idle (
            G_OBJECT (self),
            callback,
            user_data,
            error);
        g_object_unref (data);
        g_object_unref (modem);
        return;
    }

    g_object_unref (modem);

    mm_dbg ("Launching connection with QMI port (%s/%s) and data port (%s/%s)",
            mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (qmi))),
            mm_port_get_device (MM_PORT (qmi)),
            mm_port_subsys_get_string (mm_port_get_subsys (data)),
            mm_port_get_device (data));

    ctx = g_slice_new0 (ConnectContext);
    ctx->self = g_object_ref (self);
    ctx->qmi = qmi;
    ctx->data = data;
    ctx->cancellable = g_object_ref (cancellable);
    ctx->step = CONNECT_STEP_FIRST;
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             connect);

    g_object_get (self,
                  MM_BEARER_CONFIG, &properties,
                  NULL);

    if (properties) {
        MMBearerAllowedAuth auth;

        ctx->apn = g_strdup (mm_bearer_properties_get_apn (properties));
        ctx->user = g_strdup (mm_bearer_properties_get_user (properties));
        ctx->password = g_strdup (mm_bearer_properties_get_password (properties));
        switch (mm_bearer_properties_get_ip_type (properties)) {
        case MM_BEARER_IP_FAMILY_IPV4:
            ctx->ipv4 = TRUE;
            ctx->ipv6 = FALSE;
            break;
        case MM_BEARER_IP_FAMILY_IPV6:
            ctx->ipv4 = FALSE;
            ctx->ipv6 = TRUE;
            break;
        case MM_BEARER_IP_FAMILY_IPV4V6:
            ctx->ipv4 = TRUE;
            ctx->ipv6 = TRUE;
            break;
        case MM_BEARER_IP_FAMILY_UNKNOWN:
        default:
            mm_dbg ("No specific IP family requested, defaulting to IPv4");
            ctx->no_ip_family_preference = TRUE;
            ctx->ipv4 = TRUE;
            ctx->ipv6 = FALSE;
            break;
        }

        auth = mm_bearer_properties_get_allowed_auth (properties);
        g_object_unref (properties);

        if (auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
            mm_dbg ("Using default (PAP) authentication method");
            ctx->auth = QMI_WDS_AUTHENTICATION_PAP;
        } else if (auth & (MM_BEARER_ALLOWED_AUTH_PAP |
                           MM_BEARER_ALLOWED_AUTH_CHAP |
                           MM_BEARER_ALLOWED_AUTH_NONE)) {
            /* Only PAP and/or CHAP or NONE are supported */
            ctx->auth = mm_bearer_allowed_auth_to_qmi_authentication (auth);
        } else {
            gchar *str;

            str = mm_bearer_allowed_auth_build_string_from_mask (auth);
            g_simple_async_result_set_error (
                ctx->result,
                MM_CORE_ERROR,
                MM_CORE_ERROR_UNSUPPORTED,
                "Cannot use any of the specified authentication methods (%s)",
                str);
            g_free (str);
            connect_context_complete_and_free (ctx);
            return;
        }
    }

    /* Run! */
    connect_context_step (ctx);
}
static void
disconnect_3gpp_context_step (Disconnect3gppContext *ctx)
{
    switch (ctx->step) {
    case DISCONNECT_3GPP_CONTEXT_STEP_FIRST:
        /* Store the context */
        ctx->self->priv->disconnect_pending = ctx;

        /* We ignore any pending network-initiated disconnection in order to prevent it
         * from interfering with the client-initiated disconnection, as we would like to
         * proceed with the latter anyway. */
        if (ctx->self->priv->network_disconnect_pending_id != 0) {
            g_source_remove (ctx->self->priv->network_disconnect_pending_id);
            ctx->self->priv->network_disconnect_pending_id = 0;
        }

        ctx->step++;
        /* Fall down to the next step */

    case DISCONNECT_3GPP_CONTEXT_STEP_NDISDUP:
        mm_base_modem_at_command_full (ctx->modem,
                                       ctx->primary,
                                       "^NDISDUP=1,0",
                                       3,
                                       FALSE,
                                       FALSE,
                                       NULL,
                                       (GAsyncReadyCallback)disconnect_ndisdup_ready,
                                       g_object_ref (ctx->self));
        return;

    case DISCONNECT_3GPP_CONTEXT_STEP_NDISSTATQRY:
        /* If too many retries (1s of wait between the retries), failed */
        if (ctx->check_count > 60) {
            /* Clear context */
            ctx->self->priv->disconnect_pending = NULL;
            g_simple_async_result_set_error (ctx->result,
                                             MM_MOBILE_EQUIPMENT_ERROR,
                                             MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT,
                                             "Disconnection attempt timed out");
            disconnect_3gpp_context_complete_and_free (ctx);
            return;
        }

        /* Give up if too many unexpected responses to NIDSSTATQRY are encountered. */
        if (ctx->failed_ndisstatqry_count > 10) {
            /* Clear context */
            ctx->self->priv->disconnect_pending = NULL;
            g_simple_async_result_set_error (ctx->result,
                                             MM_MOBILE_EQUIPMENT_ERROR,
                                             MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
                                             "Disconnection attempt not supported.");
            disconnect_3gpp_context_complete_and_free (ctx);
            return;
        }

        /* Check if disconnected */
        ctx->check_count++;
        mm_base_modem_at_command_full (ctx->modem,
                                       ctx->primary,
                                       "^NDISSTATQRY?",
                                       3,
                                       FALSE,
                                       FALSE,
                                       NULL,
                                       (GAsyncReadyCallback)disconnect_ndisstatqry_check_ready,
                                       g_object_ref (ctx->self));
        return;

    case DISCONNECT_3GPP_CONTEXT_STEP_LAST:
        /* Clear context */
        ctx->self->priv->disconnect_pending = NULL;
        /* Set data port as result */
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        disconnect_3gpp_context_complete_and_free (ctx);
        return;
    }
}
static void
load_desktop_file (GFile        *file,
                   GAsyncResult *result,
                   GAsyncResult *init_result)
{
  HDImagesetBackground *background = HD_IMAGESET_BACKGROUND (g_async_result_get_source_object (init_result));
  HDImagesetBackgroundPrivate *priv = background->priv;
  char *file_contents = NULL;
  gsize file_size;
  char *etag;
  GKeyFile *key_file = NULL;
  guint i;
  GError *error = NULL;
  char *type = NULL;
  g_file_load_contents_finish (file,
                               result,
                               &file_contents,
                               &file_size,
                               &etag,
                               &error);
  if (error)
    {
      g_simple_async_result_set_from_error (G_SIMPLE_ASYNC_RESULT (init_result),
                                            error);
      g_error_free (error);
      goto complete;
    }
  
  key_file = g_key_file_new ();
  g_key_file_load_from_data (key_file,
                             file_contents,
                             file_size,
                             G_KEY_FILE_NONE,
                             &error);
  if (error)
    {
      g_simple_async_result_set_from_error (G_SIMPLE_ASYNC_RESULT (init_result),
                                            error);
      g_error_free (error);
      goto complete;
    }

  type = g_key_file_get_string (key_file,
                                G_KEY_FILE_DESKTOP_GROUP,
                                G_KEY_FILE_DESKTOP_KEY_TYPE,
                                &error);
  if (error)
    {
      g_simple_async_result_set_from_error (G_SIMPLE_ASYNC_RESULT (init_result),
                                            error);
      g_error_free (error);
      goto complete;
    }
  else if (g_strcmp0 (type, KEY_FILE_BACKGROUND_VALUE_TYPE) != 0)
    {
      g_simple_async_result_set_error (G_SIMPLE_ASYNC_RESULT (init_result),
                                       G_IO_ERROR,
                                       G_IO_ERROR_FAILED,
                                       "Not a valid imageset .desktop file. Type needs to be Background Image");
    }

  priv->name = g_key_file_get_string (key_file,
                                      G_KEY_FILE_DESKTOP_GROUP,
                                      G_KEY_FILE_DESKTOP_KEY_NAME,
                                      &error);
  if (error)
    {
      g_simple_async_result_set_from_error (G_SIMPLE_ASYNC_RESULT (init_result),
                                            error);
      g_error_free (error);
      goto complete;
    }

  int max_value = HD_DESKTOP_VIEWS;  

  if(hd_backgrounds_is_portrait_wallpaper_enabled (hd_backgrounds_get ()))
    max_value += HD_DESKTOP_VIEWS;

  for (i = 0; i < max_value; i++)
    {
      gchar *key, *value;
      GFile *image_file;

      if (i >= HD_DESKTOP_VIEWS)
        key = g_strdup_printf ("X-Portrait-File%u", i + 1 - HD_DESKTOP_VIEWS);
      else
        key = g_strdup_printf ("X-File%u", i + 1);

      value = g_key_file_get_string  (key_file,
                                      G_KEY_FILE_DESKTOP_GROUP,
                                      key,
                                      &error);
      g_free (key);

      if (error)
        {
          g_error_free (error);
          error = NULL;          
          g_free (value);
          continue;
        }

      g_strstrip (value);
      if (g_path_is_absolute (value))
        image_file = g_file_new_for_path (value);
      else
        {
          GFile *desktop_parent = g_file_get_parent (file);
          image_file = g_file_get_child (desktop_parent,
                                         value);
          g_object_unref (desktop_parent);
        }

      g_free (value);

      if (g_file_query_exists (image_file,
                               NULL))
        {
          hd_object_vector_push_back (priv->image_files,
                                      image_file);
          g_object_unref (image_file);
        }
      else
        {
          char *path = g_file_get_path (image_file);
          g_simple_async_result_set_error (G_SIMPLE_ASYNC_RESULT (init_result),
                                           G_IO_ERROR,
                                           G_IO_ERROR_NOT_FOUND,
                                           "Could not find file %s",
                                           path);
          g_object_unref (image_file);
          g_free (path);
          goto complete;
        }
    }

  g_simple_async_result_set_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (init_result),
                                             TRUE);

complete:
  g_free (file_contents);
  g_free (type);
  if (key_file)
    g_key_file_free (key_file);

  g_simple_async_result_complete (G_SIMPLE_ASYNC_RESULT (init_result));
}
static void
connect_3gpp_context_step (Connect3gppContext *ctx)
{
    /* Check for cancellation */
    if (g_cancellable_is_cancelled (ctx->cancellable)) {
        /* Clear context */
        ctx->self->priv->connect_pending = NULL;

        /* If we already sent the connetion command, send the disconnection one */
        if (ctx->step > CONNECT_3GPP_CONTEXT_STEP_NDISDUP)
            mm_base_modem_at_command_full (ctx->modem,
                                           ctx->primary,
                                           "^NDISDUP=1,0",
                                           3,
                                           FALSE,
                                           FALSE,
                                           NULL,
                                           NULL, /* Do not care the AT response */
                                           NULL);

        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_CANCELLED,
                                         "Huawei connection operation has been cancelled");
        connect_3gpp_context_complete_and_free (ctx);
        return;
    }

    /* Network-initiated disconnect should not be outstanding at this point,
     * because it interferes with the connect attempt.
     */
    g_assert (ctx->self->priv->network_disconnect_pending_id == 0);

    switch (ctx->step) {
    case CONNECT_3GPP_CONTEXT_STEP_FIRST: {
        MMBearerIpFamily ip_family;

        ip_family = mm_bearer_properties_get_ip_type (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
        if (ip_family == MM_BEARER_IP_FAMILY_NONE ||
            ip_family == MM_BEARER_IP_FAMILY_ANY) {
            gchar *ip_family_str;

            ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER (ctx->self));
            ip_family_str = mm_bearer_ip_family_build_string_from_mask (ip_family);
            mm_dbg ("No specific IP family requested, defaulting to %s",
                    ip_family_str);
            g_free (ip_family_str);
        }

        if (ip_family != MM_BEARER_IP_FAMILY_IPV4) {
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_UNSUPPORTED,
                                             "Only IPv4 is supported by this modem");
            connect_3gpp_context_complete_and_free (ctx);
            return;
        }

        /* Store the context */
        ctx->self->priv->connect_pending = ctx;

        ctx->step++;
        /* Fall down to the next step */
    }

    case CONNECT_3GPP_CONTEXT_STEP_NDISDUP: {
        const gchar         *apn;
        const gchar         *user;
        const gchar         *passwd;
        MMBearerAllowedAuth  auth;
        gint                 encoded_auth = MM_BEARER_HUAWEI_AUTH_UNKNOWN;
        gchar               *command;

        apn = mm_bearer_properties_get_apn (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
        user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
        passwd = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
        auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
        encoded_auth = huawei_parse_auth_type (auth);

        /* Default to no authentication if not specified */
        if ((encoded_auth = huawei_parse_auth_type (auth)) == MM_BEARER_HUAWEI_AUTH_UNKNOWN)
            encoded_auth = MM_BEARER_HUAWEI_AUTH_NONE;

        if (!user && !passwd)
            command = g_strdup_printf ("AT^NDISDUP=1,1,\"%s\"",
                                       apn == NULL ? "" : apn);
        else if (encoded_auth == MM_BEARER_HUAWEI_AUTH_NONE)
            command = g_strdup_printf ("AT^NDISDUP=1,1,\"%s\",\"%s\",\"%s\"",
                                       apn == NULL ? "" : apn,
                                       user == NULL ? "" : user,
                                       passwd == NULL ? "" : passwd);
        else
            command = g_strdup_printf ("AT^NDISDUP=1,1,\"%s\",\"%s\",\"%s\",%d",
                                       apn == NULL ? "" : apn,
                                       user == NULL ? "" : user,
                                       passwd == NULL ? "" : passwd,
                                       encoded_auth);

        mm_base_modem_at_command_full (ctx->modem,
                                       ctx->primary,
                                       command,
                                       3,
                                       FALSE,
                                       FALSE,
                                       NULL,
                                       (GAsyncReadyCallback)connect_ndisdup_ready,
                                       g_object_ref (ctx->self));
        g_free (command);
        return;
    }

    case CONNECT_3GPP_CONTEXT_STEP_NDISSTATQRY:
        /* Wait for dial up timeout, retries for 60 times
         * (1s between the retries, so it means 1 minute).
         * If too many retries, failed
         */
        if (ctx->check_count > 60) {
            /* Clear context */
            ctx->self->priv->connect_pending = NULL;
            g_simple_async_result_set_error (ctx->result,
                                             MM_MOBILE_EQUIPMENT_ERROR,
                                             MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT,
                                             "Connection attempt timed out");
            connect_3gpp_context_complete_and_free (ctx);
            return;
        }

        /* Give up if too many unexpected responses to NIDSSTATQRY are encountered. */
        if (ctx->failed_ndisstatqry_count > 10) {
            /* Clear context */
            ctx->self->priv->connect_pending = NULL;
            g_simple_async_result_set_error (ctx->result,
                                             MM_MOBILE_EQUIPMENT_ERROR,
                                             MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
                                             "Connection attempt not supported.");
            connect_3gpp_context_complete_and_free (ctx);
            return;
        }

        /* Check if connected */
        ctx->check_count++;
        mm_base_modem_at_command_full (ctx->modem,
                                       ctx->primary,
                                       "^NDISSTATQRY?",
                                       3,
                                       FALSE,
                                       FALSE,
                                       NULL,
                                       (GAsyncReadyCallback)connect_ndisstatqry_check_ready,
                                       g_object_ref (ctx->self));
        return;

    case CONNECT_3GPP_CONTEXT_STEP_LAST:
        /* Clear context */
        ctx->self->priv->connect_pending = NULL;

        /* Setup result */
        {
            MMBearerIpConfig *ipv4_config;

            ipv4_config = mm_bearer_ip_config_new ();
            mm_bearer_ip_config_set_method (ipv4_config, MM_BEARER_IP_METHOD_DHCP);
            g_simple_async_result_set_op_res_gpointer (
                ctx->result,
                mm_bearer_connect_result_new (ctx->data, ipv4_config, NULL),
                (GDestroyNotify)mm_bearer_connect_result_unref);
            g_object_unref (ipv4_config);
        }

        connect_3gpp_context_complete_and_free (ctx);
        return;
    }
}
static void
ip_config_ready (MMBaseModem *modem,
                 GAsyncResult *res,
                 GetIpConfig3gppContext *ctx)
{
    MMBearerIpConfig *ip_config = NULL;
    const gchar *response;
    GError *error = NULL;
    gchar **items;
    gchar *dns[3] = { 0 };
    guint i;
    guint dns_i;
    guint32 tmp;

    response = mm_base_modem_at_command_full_finish (MM_BASE_MODEM (modem), res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        get_ip_config_context_complete_and_free (ctx);
        return;
    }

    /* TODO: use a regex to parse this */

    /* Check result */
    if (!g_str_has_prefix (response, OWANDATA_TAG)) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Couldn't get IP config: invalid response '%s'",
                                         response);
        get_ip_config_context_complete_and_free (ctx);
        return;
    }

    response = mm_strip_tag (response, OWANDATA_TAG);
    items = g_strsplit (response, ", ", 0);

    for (i = 0, dns_i = 0; items[i]; i++) {
        if (i == 0) { /* CID */
            glong num;

            errno = 0;
            num = strtol (items[i], NULL, 10);
            if (errno != 0 || num < 0 || (gint) num != ctx->cid) {
                error = g_error_new (MM_CORE_ERROR,
                                     MM_CORE_ERROR_FAILED,
                                     "Unknown CID in OWANDATA response ("
                                     "got %d, expected %d)", (guint) num, ctx->cid);
                break;
            }
        } else if (i == 1) { /* IP address */
            if (!inet_pton (AF_INET, items[i], &tmp))
                break;

            ip_config = mm_bearer_ip_config_new ();
            mm_bearer_ip_config_set_method (ip_config, MM_BEARER_IP_METHOD_STATIC);
            mm_bearer_ip_config_set_address (ip_config,  items[i]);
        } else if (i == 3 || i == 4) { /* DNS entries */
            if (!inet_pton (AF_INET, items[i], &tmp)) {
                g_clear_object (&ip_config);
                break;
            }

            dns[dns_i++] = items[i];
        }
    }

    if (!ip_config) {
        if (error)
            g_simple_async_result_take_error (ctx->result, error);
        else
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "Couldn't get IP config: couldn't parse response '%s'",
                                             response);
    } else {
        /* If we got DNS entries, set them in the IP config */
        if (dns[0])
            mm_bearer_ip_config_set_dns (ip_config, (const gchar **)dns);

        g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                   ip_config,
                                                   (GDestroyNotify)g_object_unref);
    }

    get_ip_config_context_complete_and_free (ctx);
    g_strfreev (items);
}
Example #14
0
static void
imsi_read_ready (MMBaseModem *modem,
                 GAsyncResult *res,
                 GSimpleAsyncResult *simple)
{
    GError *error = NULL;
    const gchar *response, *str;
    gchar buf[19];
    gchar imsi[16];
    gsize len = 0;
    gint sw1, sw2;
    gint i;

    response = mm_base_modem_at_command_finish (modem, res, &error);
    if (!response) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    memset (buf, 0, sizeof (buf));
    str = mm_strip_tag (response, "+CRSM:");

    /* With or without quotes... */
    if (sscanf (str, "%d,%d,\"%18c\"", &sw1, &sw2, (char *) &buf) != 3 &&
        sscanf (str, "%d,%d,%18c", &sw1, &sw2, (char *) &buf) != 3) {
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Failed to parse the CRSM response: '%s'",
                                         response);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    if ((sw1 != 0x90 || sw2 != 0x00) &&
        (sw1 != 0x91) &&
        (sw1 != 0x92) &&
        (sw1 != 0x9f)) {
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
                                         sw1, sw2);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    /* Make sure the buffer is only digits or 'F' */
    for (len = 0; len < sizeof (buf) && buf[len]; len++) {
        if (isdigit (buf[len]))
            continue;
        if (buf[len] == 'F' || buf[len] == 'f') {
            buf[len] = 'F';  /* canonicalize the F */
            continue;
        }
        if (buf[len] == '\"') {
            buf[len] = 0;
            break;
        }

        /* Invalid character */
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "CRSM IMSI response contained invalid character '%c'",
                                         buf[len]);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    /* BCD encoded IMSIs plus the length byte and parity are 18 digits long */
    if (len != 18) {
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Invalid +CRSM IMSI response size (was %zd, expected 18)",
                                         len);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    /* Skip the length byte (digit 0-1) and parity (digit 3). Swap digits in
     * the EFimsi response to get the actual IMSI, each group of 2 digits is
     * reversed in the +CRSM response.  i.e.:
     *
     *    **0*21436587a9cbed -> 0123456789abcde
     */
    memset (imsi, 0, sizeof (imsi));
    imsi[0] = buf[2];
    for (i = 1; i < 8; i++) {
        imsi[(i * 2) - 1] = buf[(i * 2) + 3];
        imsi[i * 2] = buf[(i * 2) + 2];
    }

    /* Zero out the first F, if any, for IMSIs shorter than 15 digits */
    for (i = 0; i < 15; i++) {
        if (imsi[i] == 'F') {
            imsi[i++] = 0;
            break;
        }
    }

    /* Ensure all 'F's, if any, are at the end */
    for (; i < 15; i++) {
        if (imsi[i] != 'F') {
            g_simple_async_result_set_error (simple,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "Invalid +CRSM IMSI length (unexpected F)");
            g_simple_async_result_complete (simple);
            g_object_unref (simple);
            return;
        }
    }

    g_simple_async_result_set_op_res_gpointer (simple, imsi, NULL);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}
static gboolean
fetch_uri_job (GIOSchedulerJob *sched_job,
               GCancellable *cancellable,
               gpointer user_data)
{
  FetchUriJob *job = user_data;
  Mb5Metadata metadata;
  Mb5Query query;
  Mb5Release release;
  Mb5ReleaseList release_list;
  gchar *retval = NULL;
  gchar **param_names = NULL;
  gchar **param_values = NULL;

  query = mb5_query_new ("sushi", NULL, 0);

  param_names = g_new (gchar*, 3);
  param_values = g_new (gchar*, 3);

  param_names[0] = g_strdup ("query");
  param_values[0] = g_strdup_printf ("artist:\"%s\" AND release:\"%s\"", job->artist, job->album);

  param_names[1] = g_strdup ("limit");
  param_values[1] = g_strdup ("10");

  param_names[2] = NULL;
  param_values[2] = NULL;

  metadata = mb5_query_query (query, "release", "", "",
                              2, param_names, param_values);

  mb5_query_delete (query);

  if (metadata) {
    release_list = mb5_metadata_get_releaselist (metadata);
    int i;
    int release_list_length = mb5_release_list_size (release_list);
    for (i = 0; i < release_list_length; i++) {
      gchar asin[255];

      release = mb5_release_list_item (release_list, i);
      mb5_release_get_asin (release, asin, 255);

      if (asin != NULL &&
        asin[0] != '\0') {
        retval = g_strdup (asin);
        break;
      }
    }
  }
  mb5_metadata_delete (metadata);

  if (retval == NULL) {
    /* FIXME: do we need a better error? */
    g_simple_async_result_set_error (job->result,
                                     G_IO_ERROR,
                                     0, "%s",
                                     "Error getting the ASIN from MusicBrainz");
  } else {
    g_simple_async_result_set_op_res_gpointer (job->result,
                                               retval, NULL);
  }

  g_io_scheduler_job_send_to_mainloop_async (sched_job,
                                             fetch_uri_job_callback,
                                             job, NULL);
  g_strfreev (param_names);
  g_strfreev (param_values);
  return FALSE;
}
Example #16
0
static void
cockpit_auth_remote_login_async (CockpitAuth *self,
                                 const gchar *path,
                                 GHashTable *headers,
                                 const gchar *remote_peer,
                                 GAsyncReadyCallback callback,
                                 gpointer user_data)
{
  GSimpleAsyncResult *task;
  CockpitCreds *creds = NULL;
  RemoteLoginData *rl;
  const gchar *application;
  const gchar *password;
  gchar *memory = NULL;
  GBytes *input;
  gchar *type = NULL;
  gchar *user = NULL;

  task = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                    cockpit_auth_remote_login_async);

  application = auth_parse_application (path, &memory);
  input = cockpit_auth_parse_authorization (headers, &type);

  if (application && type && input && g_str_equal (type, "basic"))
    {
      password = parse_basic_auth_password (input, &user);
      if (password && user)
        {
          creds = cockpit_creds_new (user,
                                     application,
                                     COCKPIT_CRED_PASSWORD, password,
                                     COCKPIT_CRED_RHOST, remote_peer,
                                     NULL);
        }
      g_free (user);
    }

  if (creds)
    {
      rl = g_new0 (RemoteLoginData, 1);
      rl->creds = creds;
      rl->transport = g_object_new (COCKPIT_TYPE_SSH_TRANSPORT,
                                    "host", "127.0.0.1",
                                    "port", cockpit_ws_specific_ssh_port,
                                    "command", cockpit_ws_bridge_program,
                                    "creds", creds,
                                    "ignore-key", TRUE,
                                    NULL);

      g_simple_async_result_set_op_res_gpointer (task, rl, remote_login_data_free);
      g_signal_connect (rl->transport, "result", G_CALLBACK (on_remote_login_done), g_object_ref (task));
    }
  else
    {
      g_simple_async_result_set_error (task, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED,
                                       "Basic authentication required");
      g_simple_async_result_complete_in_idle (task);
    }

  g_free (type);
  g_free (memory);
  g_object_unref (task);
}
static void
release_cid_ready (QmiDevice *device,
                   GAsyncResult *res,
                   ReleaseCidContext *ctx)
{
    GError *error = NULL;
    QmiMessage *reply;
    guint8 cid;
    QmiService service;

    reply = qmi_device_command_finish (device, res, &error);
    if (!reply) {
        g_prefix_error (&error, "CID release failed: ");
        g_simple_async_result_take_error (ctx->result, error);
        release_cid_context_complete_and_free (ctx);
        return;
    }

    /* Parse reply */
    cid = 0;
    service = QMI_SERVICE_UNKNOWN;
    if (!qmi_message_ctl_release_cid_reply_parse (reply, &cid, &service, &error)) {
        g_prefix_error (&error, "CID release reply parsing failed: ");
        g_simple_async_result_take_error (ctx->result, error);
        release_cid_context_complete_and_free (ctx);
        qmi_message_unref (reply);
        return;
    }

    /* The service we got must match the one we requested */
    if (service != ctx->service) {
        g_simple_async_result_set_error (ctx->result,
                                         QMI_CORE_ERROR,
                                         QMI_CORE_ERROR_FAILED,
                                         "Service mismatch (%s vs %s)",
                                         qmi_service_get_string (service),
                                         qmi_service_get_string (ctx->service));
        release_cid_context_complete_and_free (ctx);
        qmi_message_unref (reply);
        return;
    }

    /* The cid we got must match the one we requested */
    if (cid != ctx->cid) {
        g_simple_async_result_set_error (ctx->result,
                                         QMI_CORE_ERROR,
                                         QMI_CORE_ERROR_FAILED,
                                         "CID mismatch (%s vs %s)",
                                         qmi_service_get_string (service),
                                         qmi_service_get_string (ctx->service));
        release_cid_context_complete_and_free (ctx);
        qmi_message_unref (reply);
        return;
    }

    g_debug ("Released client ID '%u' for service '%s'",
             cid,
             qmi_service_get_string (service));

    /* Set the CID as result */
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    release_cid_context_complete_and_free (ctx);
    qmi_message_unref (reply);
}
static void
wwsm_read_ready (MMBaseModem *self,
                 GAsyncResult *res,
                 GSimpleAsyncResult *simple)
{
    GRegex *r;
    GMatchInfo *match_info = NULL;
    LoadAllowedModesResult result;
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!response) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    result.allowed = MM_MODEM_MODE_NONE;
    result.preferred = MM_MODEM_MODE_NONE;

    /* Possible responses:
     *   +WWSM: 0    (2G only)
     *   +WWSM: 1    (3G only)
     *   +WWSM: 2,0  (Any)
     *   +WWSM: 2,1  (2G preferred)
     *   +WWSM: 2,2  (3G preferred)
     */
    r = g_regex_new ("\\r\\n\\+WWSM: ([0-2])(,([0-2]))?.*$", 0, 0, NULL);
    g_assert (r != NULL);

    if (g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, NULL)) {
        guint allowed = 0;

        if (mm_get_uint_from_match_info (match_info, 1, &allowed)) {
            switch (allowed) {
            case 0:
                result.allowed = MM_MODEM_MODE_2G;
                result.preferred = MM_MODEM_MODE_NONE;
                break;
            case 1:
                result.allowed = MM_MODEM_MODE_3G;
                result.preferred = MM_MODEM_MODE_NONE;
                break;
            case 2: {
                guint preferred = 0;

                result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);

                /* 3, to avoid the comma */
                if (mm_get_uint_from_match_info (match_info, 3, &preferred)) {
                    switch (preferred) {
                    case 0:
                        result.preferred = MM_MODEM_MODE_NONE;
                        break;
                    case 1:
                        result.preferred = MM_MODEM_MODE_2G;
                        break;
                    case 2:
                        result.preferred = MM_MODEM_MODE_3G;
                        break;
                    default:
                        g_warn_if_reached ();
                        break;
                    }
                }
                break;
            }
            default:
                g_warn_if_reached ();
                break;
            }
        }
    }

    if (result.allowed == MM_MODEM_MODE_NONE)
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Unknown wireless data service reply: '%s'",
                                         response);
    else
        g_simple_async_result_set_op_res_gpointer (simple, &result, NULL);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);

    g_regex_unref (r);
    if (match_info)
        g_match_info_free (match_info);
}
Example #19
0
static void
cockpit_auth_resume_async (CockpitAuth *self,
                           const gchar *application,
                           const gchar *type,
                           GHashTable *headers,
                           const gchar *remote_peer,
                           GAsyncReadyCallback callback,
                           gpointer user_data)
{
  AuthData *ad = NULL;
  GSimpleAsyncResult *task;
  GBytes *input = NULL;
  gchar **parts = NULL;
  gchar *header = NULL;
  gsize length;

  header = g_hash_table_lookup (headers, "Authorization");
  if (header)
    parts = g_strsplit (header, " ", 3);

  if (parts && g_strv_length (parts) == 3)
      ad = g_hash_table_lookup (self->authentication_pending, parts[1]);

  if (!ad)
    {
      task = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                        cockpit_auth_none_login_async);

      g_simple_async_result_set_error (task, COCKPIT_ERROR,
                                       COCKPIT_ERROR_AUTHENTICATION_FAILED,
                                       "Invalid resume token");
      g_simple_async_result_complete_in_idle (task);
    }
  else
    {

      task = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                        ad->tag);
      g_simple_async_result_set_op_res_gpointer (task, auth_data_ref (ad), auth_data_unref);
      g_hash_table_remove (self->authentication_pending, parts[1]);

      if (!g_base64_decode_inplace (parts[2], &length) || length < 1)
        {
          g_simple_async_result_set_error (task, COCKPIT_ERROR,
                                           COCKPIT_ERROR_AUTHENTICATION_FAILED,
                                           "Invalid resume token");
          g_simple_async_result_complete_in_idle (task);
        }
      else
        {
          input = g_bytes_new (parts[2], length);
          auth_data_add_pending_result (ad, task);
          cockpit_auth_process_write_auth_bytes (ad->auth_process, input);
          g_bytes_unref (input);
        }
    }

  if (parts)
    g_strfreev (parts);
  g_object_unref (task);
}
static void
current_ms_class_ready (MMBaseModem *self,
                        GAsyncResult *res,
                        GSimpleAsyncResult *simple)
{
    LoadAllowedModesResult result;
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!response) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    response = mm_strip_tag (response, "+CGCLASS:");

    if (strncmp (response,
                 WAVECOM_MS_CLASS_A_IDSTR,
                 strlen (WAVECOM_MS_CLASS_A_IDSTR)) == 0) {
        mm_dbg ("Modem configured as a Class A mobile station");
        /* For 3G devices, query WWSM status */
        mm_base_modem_at_command (MM_BASE_MODEM (self),
                                  "+WWSM?",
                                  3,
                                  FALSE,
                                  (GAsyncReadyCallback)wwsm_read_ready,
                                  simple);
        return;
    }

    result.allowed = MM_MODEM_MODE_NONE;
    result.preferred = MM_MODEM_MODE_NONE;

    if (strncmp (response,
                 WAVECOM_MS_CLASS_B_IDSTR,
                 strlen (WAVECOM_MS_CLASS_B_IDSTR)) == 0) {
        mm_dbg ("Modem configured as a Class B mobile station");
        result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS);
        result.preferred = MM_MODEM_MODE_2G;
    } else if (strncmp (response,
                        WAVECOM_MS_CLASS_CG_IDSTR,
                        strlen (WAVECOM_MS_CLASS_CG_IDSTR)) == 0) {
        mm_dbg ("Modem configured as a Class CG mobile station");
        result.allowed = MM_MODEM_MODE_2G;
        result.preferred = MM_MODEM_MODE_NONE;
    } else if (strncmp (response,
                        WAVECOM_MS_CLASS_CC_IDSTR,
                        strlen (WAVECOM_MS_CLASS_CC_IDSTR)) == 0) {
        mm_dbg ("Modem configured as a Class CC mobile station");
        result.allowed = MM_MODEM_MODE_CS;
        result.preferred = MM_MODEM_MODE_NONE;
    }

    if (result.allowed == MM_MODEM_MODE_NONE)
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Unknown mobile station class: '%s'",
                                         response);
    else
        g_simple_async_result_set_op_res_gpointer (simple, &result, NULL);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}
static void
set_allowed_modes (MMIfaceModem *self,
                   MMModemMode allowed,
                   MMModemMode preferred,
                   GAsyncReadyCallback callback,
                   gpointer user_data)
{
    GSimpleAsyncResult *result;
    gchar *command;
    gint cm_mode = -1;
    gint pref_acq = -1;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        set_allowed_modes);

    if (allowed == MM_MODEM_MODE_2G) {
        cm_mode = 1;
        pref_acq = 0;
    } else if (allowed == MM_MODEM_MODE_3G) {
        cm_mode = 2;
        pref_acq = 0;
    } else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)
               && !mm_iface_modem_is_3gpp_lte (self)) { /* LTE models do not support 2G|3G mode */
        cm_mode = 0;
        if (preferred == MM_MODEM_MODE_2G)
            pref_acq = 1;
        else if (preferred == MM_MODEM_MODE_3G)
            pref_acq = 2;
        else /* none preferred, so AUTO */
            pref_acq = 0;
    } else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G)) {
        cm_mode = 0;
        pref_acq = 0;
    } else if (allowed == MM_MODEM_MODE_4G) {
        cm_mode = 6;
        pref_acq = 0;
    }

    if (cm_mode < 0 || pref_acq < 0) {
        gchar *allowed_str;
        gchar *preferred_str;

        allowed_str = mm_modem_mode_build_string_from_mask (allowed);
        preferred_str = mm_modem_mode_build_string_from_mask (preferred);
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Requested mode (allowed: '%s', preferred: '%s') not "
                                         "supported by the modem.",
                                         allowed_str,
                                         preferred_str);
        g_free (allowed_str);
        g_free (preferred_str);

        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        return;
    }

    command = g_strdup_printf ("AT+ZSNT=%d,0,%d", cm_mode, pref_acq);
    mm_base_modem_at_command (
        MM_BASE_MODEM (self),
        command,
        3,
        FALSE,
        (GAsyncReadyCallback)allowed_mode_update_ready,
        result);
    g_free (command);
}
static void
set_allowed_modes (MMIfaceModem *self,
                   MMModemMode allowed,
                   MMModemMode preferred,
                   GAsyncReadyCallback callback,
                   gpointer user_data)
{
    SetAllowedModesContext *ctx;

    ctx = g_new0 (SetAllowedModesContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             set_allowed_modes);
    ctx->allowed = allowed;
    ctx->preferred = preferred;

    if (allowed == MM_MODEM_MODE_CS)
        ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CC_IDSTR);
    else if (allowed == MM_MODEM_MODE_2G)
        ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CG_IDSTR);
    else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS) &&
             preferred == MM_MODEM_MODE_NONE)
        ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_B_IDSTR);
    else if (allowed & MM_MODEM_MODE_3G) {
        if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G) ||
            allowed == (MM_MODEM_MODE_CS | MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
            if (preferred == MM_MODEM_MODE_2G)
                ctx->wwsm_command = g_strdup ("+WWSM=2,1");
            else if (preferred == MM_MODEM_MODE_3G)
                ctx->wwsm_command = g_strdup ("+WWSM=2,2");
            else if (preferred == MM_MODEM_MODE_NONE)
                ctx->wwsm_command = g_strdup ("+WWSM=2,0");
        } else if (allowed == MM_MODEM_MODE_3G)
            ctx->wwsm_command = g_strdup ("+WWSM=1");

        if (ctx->wwsm_command)
            ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_A_IDSTR);
    }

    if (!ctx->cgclass_command) {
        gchar *allowed_str;
        gchar *preferred_str;

        allowed_str = mm_modem_mode_build_string_from_mask (allowed);
        preferred_str = mm_modem_mode_build_string_from_mask (preferred);
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Requested mode (allowed: '%s', preferred: '%s') not "
                                         "supported by the modem.",
                                         allowed_str,
                                         preferred_str);
        g_free (allowed_str);
        g_free (preferred_str);

        set_allowed_modes_context_complete_and_free (ctx);
        return;
    }

    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              ctx->cgclass_command,
                              3,
                              FALSE,
                              (GAsyncReadyCallback)cgclass_update_ready,
                              ctx);
}
static
void spice_win_usb_driver_op(SpiceWinUsbDriver *self,
                             SpiceUsbDevice *device,
                             guint16 op_type,
                             GCancellable *cancellable,
                             GAsyncReadyCallback callback,
                             gpointer user_data)
{
    guint16 vid, pid;
    GError *err = NULL;
    GSimpleAsyncResult *result;
    SpiceWinUsbDriverPrivate *priv;

    g_return_if_fail(SPICE_IS_WIN_USB_DRIVER(self));
    g_return_if_fail(device != NULL);

    priv = self->priv;

    result = g_simple_async_result_new(G_OBJECT(self), callback, user_data,
                                       spice_win_usb_driver_op);

    if (priv->result) { /* allow one install/uninstall request at a time */
        g_warning("Another request exists -- try later");
        g_simple_async_result_set_error(result,
                  SPICE_WIN_USB_DRIVER_ERROR, SPICE_WIN_USB_DRIVER_ERROR_FAILED,
                  "Another request exists -- try later");
        goto failed_request;
    }


    vid = spice_usb_device_get_vid(device);
    pid = spice_usb_device_get_pid(device);

    if (! priv->handle ) {
        SPICE_DEBUG("win-usb-driver-install: connecting to usbclerk named pipe");
        priv->handle = CreateFile(USB_CLERK_PIPE_NAME,
                                  GENERIC_READ | GENERIC_WRITE,
                                  0, NULL,
                                  OPEN_EXISTING,
                                  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                                  NULL);
        if (priv->handle == INVALID_HANDLE_VALUE) {
            DWORD errval  = GetLastError();
            gchar *errstr = g_win32_error_message(errval);
            g_warning("failed to create a named pipe to usbclerk (%ld) %s",
                      errval,errstr);
            g_simple_async_result_set_error(result,
                      G_IO_ERROR, G_IO_ERROR_FAILED,
                      "Failed to create named pipe (%ld) %s", errval, errstr);
            goto failed_request;
        }
    }

    if (!spice_win_usb_driver_send_request(self, op_type,
                                           vid, pid, &err)) {
        g_warning("failed to send a request to usbclerk %s", err->message);
        g_simple_async_result_take_error(result, err);
        goto failed_request;
    }

    /* set up for async read */
    priv->result = result;
    priv->device = device;
    priv->cancellable = cancellable;

    spice_win_usb_driver_read_reply_async(self);

    return;

 failed_request:
    g_simple_async_result_complete_in_idle(result);
    g_clear_object(&result);
}
static void
set_bands_3g (MMIfaceModem *self,
              GArray *bands_array,
              GSimpleAsyncResult *result)
{
    GArray *bands_array_final;
    guint wavecom_band = 0;
    guint i;
    gchar *bands_string;
    gchar *cmd;

    /* The special case of ANY should be treated separately. */
    if (bands_array->len == 1 &&
        g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) {
        /* We build an array with all bands to set; so that we use the same
         * logic to build the cinterion_band, and so that we can log the list of
         * bands being set properly */
        bands_array_final = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (bands_3g));
        for (i = 0; i < G_N_ELEMENTS (bands_3g); i++)
            g_array_append_val (bands_array_final, bands_3g[i].mm_band);
    } else
        bands_array_final = g_array_ref (bands_array);

    for (i = 0; i < G_N_ELEMENTS (bands_3g); i++) {
        guint j;

        for (j = 0; j < bands_array_final->len; j++) {
            if (g_array_index (bands_array_final, MMModemBand, j) == bands_3g[i].mm_band) {
                wavecom_band |= bands_3g[i].wavecom_band_flag;
                break;
            }
        }
    }

    bands_string = mm_common_build_bands_string ((MMModemBand *)bands_array_final->data,
                                                 bands_array_final->len);
    g_array_unref (bands_array_final);

    if (wavecom_band == 0) {
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_UNSUPPORTED,
                                         "The given band combination is not supported: '%s'",
                                         bands_string);
        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        g_free (bands_string);
        return;
    }

    mm_dbg ("Setting new bands to use: '%s'", bands_string);
    cmd = g_strdup_printf ("+WMBS=\"%u\",1", wavecom_band);
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              cmd,
                              3,
                              FALSE,
                              (GAsyncReadyCallback)wmbs_set_ready,
                              result);
    g_free (cmd);
    g_free (bands_string);
}
static void
gabble_server_sasl_channel_abort_sasl (
    TpSvcChannelInterfaceSASLAuthentication *channel,
    guint in_Reason,
    const gchar *in_Debug_Message,
    DBusGMethodInvocation *context)
{
  GabbleServerSaslChannel *self = GABBLE_SERVER_SASL_CHANNEL (channel);
  GSimpleAsyncResult *r = self->priv->result;
  guint code;
  const gchar *dbus_error;

  switch (self->priv->sasl_status)
    {
      case TP_SASL_STATUS_SERVER_FAILED:
      case TP_SASL_STATUS_CLIENT_FAILED:
        DEBUG ("ignoring attempt to abort: we already failed");
        break;

      case TP_SASL_STATUS_SUCCEEDED:
      case TP_SASL_STATUS_CLIENT_ACCEPTED:
        DEBUG ("cannot abort: client already called AcceptSASL");
        gabble_server_sasl_channel_raise (context, TP_ERROR_NOT_AVAILABLE,
            "Authentication has already succeeded - too late to abort");
        return;

      case TP_SASL_STATUS_NOT_STARTED:
      case TP_SASL_STATUS_IN_PROGRESS:
      case TP_SASL_STATUS_SERVER_SUCCEEDED:
        switch (in_Reason)
          {
            case TP_SASL_ABORT_REASON_INVALID_CHALLENGE:
              DEBUG ("invalid challenge (%s)", in_Debug_Message);
              code = WOCKY_AUTH_ERROR_INVALID_REPLY;
              dbus_error = TP_ERROR_STR_SERVICE_CONFUSED;
              break;

            case TP_SASL_ABORT_REASON_USER_ABORT:
              DEBUG ("user aborted auth (%s)", in_Debug_Message);
              code = WOCKY_AUTH_ERROR_FAILURE;
              dbus_error = TP_ERROR_STR_CANCELLED;
              break;

            default:
              DEBUG ("unknown reason code %u, treating as User_Abort (%s)",
                  in_Reason, in_Debug_Message);
              code = WOCKY_AUTH_ERROR_FAILURE;
              dbus_error = TP_ERROR_STR_CANCELLED;
              break;
          }

        if (r != NULL)
          {
            self->priv->result = NULL;

            /* If Not_Started, we're returning failure from start_auth_async.
             * If In_Progress, we might be returning failure from
             *  challenge_async, if one is outstanding.
             * If Server_Succeeded, we're returning failure from success_async.
             */

            g_simple_async_result_set_error (r, WOCKY_AUTH_ERROR, code,
                "Authentication aborted: %s", in_Debug_Message);

            g_simple_async_result_complete_in_idle (r);
            g_object_unref (r);
          }

        change_current_state (self, TP_SASL_STATUS_CLIENT_FAILED,
            dbus_error, in_Debug_Message);
        break;

      default:
        g_assert_not_reached ();
    }

  tp_svc_channel_interface_sasl_authentication_return_from_abort_sasl (
      context);
}
static void
set_bands_2g (MMIfaceModem *self,
              GArray *bands_array,
              GSimpleAsyncResult *result)
{
    GArray *bands_array_final;
    gchar wavecom_band = '\0';
    guint i;
    gchar *bands_string;
    gchar *cmd;

    /* If the iface properly checked the given list against the supported bands,
     * it's not possible to get an array longer than 4 here. */
    g_assert (bands_array->len <= 4);

    /* The special case of ANY should be treated separately. */
    if (bands_array->len == 1 &&
        g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) {
        const WavecomBand2G *all;

        /* All bands is the last element in our 2G bands array */
        all = &bands_2g[G_N_ELEMENTS (bands_2g) - 1];

        /* We build an array with all bands to set; so that we use the same
         * logic to build the cinterion_band, and so that we can log the list of
         * bands being set properly */
        bands_array_final = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 4);
        g_array_append_vals (bands_array_final, all->mm_bands, all->n_mm_bands);
    } else
        bands_array_final = g_array_ref (bands_array);

    for (i = 0; wavecom_band == '\0' && i < G_N_ELEMENTS (bands_2g); i++) {
        GArray *supported_combination;

        supported_combination = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), bands_2g[i].n_mm_bands);
        g_array_append_vals (supported_combination, bands_2g[i].mm_bands, bands_2g[i].n_mm_bands);

        /* Check if the given array is exactly one of the supported combinations */
        if (mm_common_bands_garray_cmp (bands_array_final, supported_combination))
            wavecom_band = bands_2g[i].wavecom_band;

        g_array_unref (supported_combination);
    }

    bands_string = mm_common_build_bands_string ((MMModemBand *)bands_array_final->data,
                                                 bands_array_final->len);
    g_array_unref (bands_array_final);

    if (wavecom_band == '\0') {
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_UNSUPPORTED,
                                         "The given band combination is not supported: '%s'",
                                         bands_string);
        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        g_free (bands_string);
        return;
    }

    mm_dbg ("Setting new bands to use: '%s'", bands_string);
    cmd = g_strdup_printf ("+WMBS=%c,1", wavecom_band);
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              cmd,
                              3,
                              FALSE,
                              (GAsyncReadyCallback)wmbs_set_ready,
                              result);

    g_free (cmd);
    g_free (bands_string);
}
static void
huawei_custom_init_step (HuaweiCustomInitContext *ctx)
{
    FirstInterfaceContext *fi_ctx;

    /* If cancelled, end */
    if (g_cancellable_is_cancelled (ctx->cancellable)) {
        mm_dbg ("(Huawei) no need to keep on running custom init in (%s)",
                mm_port_get_device (MM_PORT (ctx->port)));
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_CANCELLED,
                                         "Custom initialization cancelled");
        huawei_custom_init_context_complete_and_free (ctx);
        return;
    }

    if (!ctx->curc_done) {
        if (ctx->curc_retries == 0) {
            /* All retries consumed, probably not an AT port */
            mm_port_probe_set_result_at (ctx->probe, FALSE);
            g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
            /* Try with next */
            try_next_usbif (mm_port_probe_peek_device (ctx->probe));
            huawei_custom_init_context_complete_and_free (ctx);
            return;
        }

        ctx->curc_retries--;
        /* Turn off unsolicited messages on secondary ports until needed */
        mm_at_serial_port_queue_command (
            ctx->port,
            "AT^CURC=0",
            3,
            FALSE, /* raw */
            ctx->cancellable,
            (MMAtSerialResponseFn)curc_ready,
            ctx);
        return;
    }

    /* Try to get a port map from the modem */
    if (!ctx->getportmode_done) {
        if (ctx->getportmode_retries == 0) {
            g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
            huawei_custom_init_context_complete_and_free (ctx);
            return;
        }

        ctx->getportmode_retries--;
        mm_at_serial_port_queue_command (
            ctx->port,
            "AT^GETPORTMODE",
            3,
            FALSE, /* raw */
            ctx->cancellable,
            (MMAtSerialResponseFn)getportmode_ready,
            ctx);
        return;
    }

    /* All done it seems */
    fi_ctx = g_object_get_data (G_OBJECT (mm_port_probe_peek_device (ctx->probe)), TAG_FIRST_INTERFACE_CONTEXT);
    g_assert (fi_ctx != NULL);
    fi_ctx->custom_init_run = TRUE;

    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    huawei_custom_init_context_complete_and_free (ctx);
}
Example #28
0
static void
list_photos_ready_cb (SoupSession *session,
		      SoupMessage *msg,
		      gpointer     user_data)
{
	FacebookService      *self = user_data;
	GSimpleAsyncResult *result;
	SoupBuffer         *body;
	DomDocument        *doc = NULL;
	GError             *error = NULL;

	result = facebook_connection_get_result (self->priv->conn);

	if (msg->status_code != 200) {
		g_simple_async_result_set_error (result,
						 SOUP_HTTP_ERROR,
						 msg->status_code,
						 "%s",
						 soup_status_get_phrase (msg->status_code));
		g_simple_async_result_complete_in_idle (result);
		return;
	}

	body = soup_message_body_flatten (msg->response_body);
	if (facebook_utils_parse_response (body, &doc, &error)) {
		DomElement *response;
		DomElement *node;
		GList      *photos = NULL;

		response = DOM_ELEMENT (doc)->first_child;
		for (node = response->first_child; node; node = node->next_sibling) {
			if (g_strcmp0 (node->tag_name, "photoset") == 0) {
				DomElement *child;
				int         position;

				position = 0;
				for (child = node->first_child; child; child = child->next_sibling) {
					if (g_strcmp0 (child->tag_name, "photo") == 0) {
						FacebookPhoto *photo;

						photo = facebook_photo_new ();
						dom_domizable_load_from_element (DOM_DOMIZABLE (photo), child);
						photo->position = position++;
						photos = g_list_prepend (photos, photo);
					}
				}
			}
		}

		photos = g_list_reverse (photos);
		g_simple_async_result_set_op_res_gpointer (result, photos, (GDestroyNotify) _g_object_list_unref);

		g_object_unref (doc);
	}
	else
		g_simple_async_result_set_from_error (result, error);

	g_simple_async_result_complete_in_idle (result);

	soup_buffer_free (body);
}
static AgAccountService *
uoa_password_common (TpAccount *tp_account,
    GSimpleAsyncResult *result,
    AgAuthData **ret_auth_data)
{
  const GValue *storage_id;
  AgAccountId account_id;
  AgManager *manager = NULL;
  AgAccount *account = NULL;
  GList *l;
  AgAccountService *service = NULL;
  AgAuthData *auth_data = NULL;

  g_assert (ret_auth_data != NULL);
  *ret_auth_data = NULL;

  storage_id = tp_account_get_storage_identifier (tp_account);
  account_id = g_value_get_uint (storage_id);
  if (account_id == 0)
    {
      g_simple_async_result_set_error (result,
          TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
          "StorageId is invalid, cannot get the AgAccount for this TpAccount");
      g_simple_async_result_complete_in_idle (result);
      goto error;
    }

  manager = empathy_uoa_manager_dup ();
  account = ag_manager_get_account (manager, account_id);

  /* Assuming there is only one IM service */
  l = ag_account_list_services_by_type (account, EMPATHY_UOA_SERVICE_TYPE);
  if (l == NULL)
    {
      g_simple_async_result_set_error (result,
          TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
          "AgAccount has no IM service");
      g_simple_async_result_complete_in_idle (result);
      goto error;
    }
  service = ag_account_service_new (account, l->data);
  ag_service_list_free (l);

  auth_data = ag_account_service_get_auth_data (service);
  if (auth_data == NULL)
    {
      g_simple_async_result_set_error (result,
          TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
          "Service has no AgAuthData");
      g_simple_async_result_complete_in_idle (result);
      goto error;
    }

  if (tp_strdiff (ag_auth_data_get_mechanism (auth_data), "password") ||
      tp_strdiff (ag_auth_data_get_method (auth_data), "password"))
    {
      g_simple_async_result_set_error (result,
          TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
          "Service does not use password authentication");
      g_simple_async_result_complete_in_idle (result);
      goto error;
    }

  g_object_unref (manager);
  g_object_unref (account);

  *ret_auth_data = auth_data;
  return service;

error:
  g_clear_object (&manager);
  g_clear_object (&account);
  g_clear_object (&service);
  tp_clear_pointer (&auth_data, ag_auth_data_unref);
  return NULL;
}
static void
set_current_modes (MMIfaceModem *self,
                   MMModemMode allowed,
                   MMModemMode preferred,
                   GAsyncReadyCallback callback,
                   gpointer user_data)
{
    GSimpleAsyncResult *result;
    gchar *command;
    gint option_mode = -1;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        set_current_modes);

    if (allowed == MM_MODEM_MODE_2G)
        option_mode = 0;
    else if (allowed == MM_MODEM_MODE_3G)
        option_mode = 1;
    else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
        if (preferred == MM_MODEM_MODE_2G)
            option_mode = 2;
        else if (preferred == MM_MODEM_MODE_3G)
            option_mode = 3;
        else /* none preferred, so AUTO */
            option_mode = 5;
    } else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
        option_mode = 5;

    if (option_mode < 0) {
        gchar *allowed_str;
        gchar *preferred_str;

        allowed_str = mm_modem_mode_build_string_from_mask (allowed);
        preferred_str = mm_modem_mode_build_string_from_mask (preferred);
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Requested mode (allowed: '%s', preferred: '%s') not "
                                         "supported by the modem.",
                                         allowed_str,
                                         preferred_str);
        g_free (allowed_str);
        g_free (preferred_str);

        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        return;
    }

    command = g_strdup_printf ("AT_OPSYS=%d,2", option_mode);
    mm_base_modem_at_command (
        MM_BASE_MODEM (self),
        command,
        3,
        FALSE,
        (GAsyncReadyCallback)allowed_mode_update_ready,
        result);
    g_free (command);
}