コード例 #1
0
ファイル: snep.c プロジェクト: justinc1985/IntelRangeley
/*
 * SNEP Core: read function
 *	This function handles SNEP REQUEST codes:
 *	GET, PUT and CONTINUE (REJECT is not handled).
 *
 *	We read the first 6 bytes (the header) and check
 *	- the read size ( should be 6 )
 *	- the version (on MAJOR)
 *
 *	Then, we check snep_data. If it exists, it means that we are in
 *	a fragment/continue situation (a 1st fragment was sent, and we
 *	expect a CONTINUE for the remaining bytes).
 *	If there's no existing snep_data, we create a new one and read the
 *	missing bytes (llcp removes fragmentation issues)
 *
 */
bool near_snep_core_read(int client_fd,
				uint32_t adapter_idx, uint32_t target_idx,
				near_tag_io_cb cb,
				near_server_io req_get,
				near_server_io req_put,
				gpointer data)
{
	struct p2p_snep_data *snep_data;
	struct p2p_snep_req_frame frame;
	int bytes_recv, ret;
	uint32_t ndef_length;

	DBG("");

	/* Check previous/pending snep_data */
	snep_data = g_hash_table_lookup(snep_client_hash,
					GINT_TO_POINTER(client_fd));

	/*
	 * If snep data is already there, and there are more bytes to read
	 * we just go ahead and read more fragments from the client.
	 */
	if (snep_data &&
			snep_data->nfc_data_length !=
					snep_data->nfc_data_current_length) {
		ret = snep_core_read_ndef(client_fd, snep_data);
		if (ret)
			return ret;

		goto process_request;
	}

	/*
	 * We already got something from this client, we should try
	 * to continue reading.
	 */
	/* TODO Try with PEEK */
	bytes_recv = recv(client_fd, &frame, sizeof(frame), 0);
	if (bytes_recv < 0) {
		near_error("Read error SNEP %d %s", bytes_recv,
							strerror(errno));
		return false;
	}

	/* Check frame size */
	if (bytes_recv != sizeof(frame)) {
		near_error("Bad frame size: %d", bytes_recv);
		return false;
	}

	/* If major is different, send UNSUPPORTED VERSION */
	if (NEAR_SNEP_MAJOR(frame.version) != NEAR_SNEP_MAJOR(NEAR_SNEP_VERSION)) {
		near_error("Unsupported version (%d)", frame.version);
		near_snep_core_response_noinfo(client_fd, NEAR_SNEP_RESP_VERSION);
		return true;
	}

	/*
	 * This is a fragmentation SNEP operation since we have pending
	 * frames. But the ndef length and the current data length are
	 * identical. So this is a CONTINUE for a fragmented GET, and
	 * we should just process a CONTINUE frame and send the fragments
	 * back to the client. This will be done from snep_core_process_request().
	 */
	if (snep_data) {
		snep_data->request = frame.request;
		goto process_request;
	}

	/* This is a new request from the client */
	snep_data = g_try_malloc0(sizeof(struct p2p_snep_data));
	if (!snep_data)
		return false;

	/* the whole frame length */
	ndef_length = GINT_FROM_BE(frame.length);

	snep_data->nfc_data = g_try_malloc0(ndef_length + TLV_SIZE);
	if (!snep_data->nfc_data) {
		g_free(snep_data);
		return false;
	}

	/* fill the struct */
	snep_data->nfc_data_length = ndef_length;
	snep_data->nfc_data_ptr = snep_data->nfc_data;
	snep_data->adapter_idx = adapter_idx;
	snep_data->target_idx = target_idx;
	snep_data->request = frame.request;
	snep_data->respond_continue = FALSE;
	snep_data->cb = cb;

	/* Add to the client hash table */
	g_hash_table_insert(snep_client_hash,
					GINT_TO_POINTER(client_fd), snep_data);

	if (ndef_length > 0) {
		if ((frame.request == NEAR_SNEP_REQ_GET) ||
				(frame.request == NEAR_SNEP_REQ_PUT)) {
			/* We should read the missing bytes */
			ret = snep_core_read_ndef(client_fd, snep_data);
			if (ret)
				return ret;
		}
	}

process_request:
	return snep_core_process_request(client_fd, snep_data,
							req_get, req_put);

}
コード例 #2
0
ファイル: backend_kwallet.c プロジェクト: EvilBit/darktable
// Get the (key,value) pairs back from KWallet.
GHashTable* dt_pwstorage_kwallet_get(const backend_kwallet_context_t *context, const gchar* slot)
{
  GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal);
  GError* error = NULL;

  // Is there an entry in the wallet?
  gboolean has_entry = FALSE;
  int wallet_handle = get_wallet_handle(context);

  /* signature:
   *
   * in  i handle,
   * in  s folder,
   * in  s key,
   * in  s appid,
   *
   * out b arg_0
   */
  GVariant *ret = g_dbus_proxy_call_sync(context->proxy,
                                         "hasEntry",
                                         g_variant_new("(isss)", wallet_handle, kwallet_folder, slot, app_id),
                                         G_DBUS_CALL_FLAGS_NONE,
                                         -1,
                                         NULL,
                                         &error);

  if(check_error(error))
  {
    g_variant_unref(ret);
    return table;
  }

  GVariant *child = g_variant_get_child_value(ret, 0);
  has_entry = g_variant_get_boolean(child);
  g_variant_unref(child);
  g_variant_unref(ret);

  if(!has_entry)
    return table;

  /* signature:
   *
   * in  i handle,
   * in  s folder,
   * in  s key,
   * in  s appid,
   *
   * out a{sv} arg_0)
   */
  ret = g_dbus_proxy_call_sync(context->proxy,
                               "readMapList",
                               g_variant_new("(isss)", wallet_handle, kwallet_folder, slot, app_id),
                               G_DBUS_CALL_FLAGS_NONE,
                               -1,
                               NULL,
                               &error);

  if(check_error(error))
  {
    g_variant_unref(ret);
    return table;
  }

  child = g_variant_get_child_value(ret, 0);

  // we are only interested in the first child. i am not even sure that there can legally be more than one
  if(g_variant_n_children(child)<1)
  {
    g_variant_unref(child);
    g_variant_unref(ret);
    return table;
  }

  GVariant *element = g_variant_get_child_value(child, 0);
  GVariant *v = NULL;
  g_variant_get(element, "{sv}", NULL, &v);

  const gchar *byte_array = g_variant_get_data(v);
  if(!byte_array)
  {
    g_variant_unref(v);
    g_variant_unref(element);
    g_variant_unref(child);
    g_variant_unref(ret);
    return table;
  }

  int entries = GINT_FROM_BE(*((int*)byte_array));
  byte_array += sizeof(gint);

  for(int i=0; i<entries; i++)
  {
    guint length;
    gchar* key = array2string(byte_array, &length);

    byte_array += length;

    gchar* value = array2string(byte_array, &length);

    byte_array += length;

    dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_get] reading (%s, %s)\n",(gchar*)key, (gchar*)value);

    g_hash_table_insert(table, key, value);
  }

  g_variant_unref(v);
  g_variant_unref(element);
  g_variant_unref(child);
  g_variant_unref(ret);

  return table;
}
コード例 #3
0
ファイル: backend_kwallet.c プロジェクト: chubinou/darktable
// Get the (key,value) pairs back from KWallet.
GHashTable* dt_pwstorage_kwallet_get(const gchar* slot)
{
  _context = (backend_kwallet_context_t*)(darktable.pwstorage->backend_context);
  GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal);
  GError* error = NULL;

  // Is there an entry in the wallet?
  gboolean has_entry = FALSE;
  int wallet_handle = get_wallet_handle();
  dbus_g_proxy_call(_context->proxy, "hasEntry", &error,
                    G_TYPE_INT,     wallet_handle,         // handle
                    G_TYPE_STRING,  kwallet_folder,        // folder
                    G_TYPE_STRING,  slot,                  // key
                    G_TYPE_STRING,  app_id,                // appid
                    G_TYPE_INVALID,
                    G_TYPE_BOOLEAN, &has_entry,
                    G_TYPE_INVALID);

  if (CheckError(error) || !has_entry)
    return table;

  GArray* byte_array = NULL;

  dbus_g_proxy_call(_context->proxy, "readMap", &error,
                    G_TYPE_INT,     wallet_handle,         // handle
                    G_TYPE_STRING,  kwallet_folder,        // folder
                    G_TYPE_STRING,  slot,                  // key
                    G_TYPE_STRING,  app_id,                // appid
                    G_TYPE_INVALID,
                    DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
                    G_TYPE_INVALID);

  if (CheckError(error) || !byte_array || !byte_array->len)
    return table;

  gint entries;
  memcpy(&entries, byte_array->data, sizeof(gint));
  entries = GINT_FROM_BE(entries);

  gchar* pos = byte_array->data + sizeof(gint);

  gint i;
  for(i=0; i<entries; ++i)
  {
    guint length;
    gchar* key = array2string(pos, &length);

    pos += length;

    gchar* value = array2string(pos, &length);

    pos += length;

    dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_get] reading (%s, %s)\n",(gchar*)key, (gchar*)value);

    g_hash_table_insert(table, key, value);
  }

  g_array_free(byte_array, TRUE);

  return table;
}