/* Signals incoming delivery receipts. http://xmpp.org/extensions/xep-0184.html
 */
static gboolean
im_factory_receipt_cb (
    WockyPorter *porter,
    WockyStanza *message,
    gpointer user_data)
{
  GabbleImFactory *self = GABBLE_IM_FACTORY (user_data);
  WockyNode *received;
  const gchar *from, *received_id;
  GabbleIMChannel *channel;

  received = wocky_node_get_child_ns (wocky_stanza_get_top_node (message),
      "received", NS_RECEIPTS);
  g_return_val_if_fail (received != NULL, FALSE);

  received_id = wocky_node_get_attribute (received, "id");
  if (received_id == NULL)
    {
      STANZA_DEBUG (message, "but *what* did you receive?!");
      return TRUE;
    }

  from = wocky_stanza_get_from (message);
  channel = get_channel_for_incoming_message (self, from, FALSE);
  if (channel == NULL)
    {
      DEBUG ("no existing channel with '%s'; ignoring receipt", from);
      return TRUE;
    }

  gabble_im_channel_receive_receipt (channel, received_id);
  return TRUE;
}
static gboolean
jingle_cb (
    WockyPorter *porter,
    WockyStanza *msg,
    gpointer user_data)
{
  GabbleJingleFactory *self = GABBLE_JINGLE_FACTORY (user_data);
  GError *error = NULL;
  const gchar *sid, *from;
  GabbleJingleSession *sess;
  gboolean new_session = FALSE;
  JingleAction action;
  JingleDialect dialect;

  /* see if it's a jingle message and detect dialect */
  sid = gabble_jingle_session_detect (msg, &action, &dialect);
  from = wocky_stanza_get_from (msg);

  if (sid == NULL || from == NULL)
    return FALSE;

  sess = ensure_session (self, sid, from, action, dialect, &new_session,
      &error);

  if (sess == NULL)
    goto REQUEST_ERROR;

  /* now act on the message */
  if (!gabble_jingle_session_parse (sess, action, msg, &error))
    goto REQUEST_ERROR;

  /* This has to be after the call to parse(), not inside create_session():
   * until the session has parsed the session-initiate stanza, it does not know
   * about its own contents, and we don't even know if the content types are
   * something we understand. So it's essentially half-alive and useless to
   * signal listeners.
   */
  if (new_session)
    g_signal_emit (self, signals[NEW_SESSION], 0, sess, FALSE);

  /* all went well, we can acknowledge the IQ */
  wocky_porter_acknowledge_iq (porter, msg, NULL);

  return TRUE;

REQUEST_ERROR:
  g_assert (error != NULL);
  DEBUG ("NAKing with error: %s", error->message);
  wocky_porter_send_iq_gerror (porter, msg, error);
  g_error_free (error);

  if (sess != NULL && new_session)
    gabble_jingle_session_terminate (sess, JINGLE_REASON_UNKNOWN, NULL, NULL);

  return TRUE;
}