Example #1
0
void
cut_setup()
{
  if (llcp_init())
    cut_fail("llcp_init() failed");

  if (!(sample_a_pdu = malloc(sizeof(*sample_a_pdu)))) {
    cut_fail("Cannot allocate sample_a_pdu");
  }

  sample_a_pdu->dsap = 0;
  sample_a_pdu->ptype = PDU_AGF;
  sample_a_pdu->ssap = 0;
  sample_a_pdu->information_size = sizeof(sample_a_pdu_information);
  sample_a_pdu->information = malloc(sizeof(sample_a_pdu_information));
  memcpy(sample_a_pdu->information, sample_a_pdu_information, sizeof(sample_a_pdu_information));

  if (!(sample_i_pdu = malloc(sizeof(*sample_i_pdu)))) {
    cut_fail("Cannot allocate sample_i_pdu");
  }

  sample_i_pdu->dsap = 8;
  sample_i_pdu->ptype = PDU_I;
  sample_i_pdu->ssap = 2;
  sample_i_pdu->ns = 5;
  sample_i_pdu->nr = 3;
  sample_i_pdu->information_size = 11;
  sample_i_pdu->information = (uint8_t *)strdup("Hello World");
}
Example #2
0
void
test_mac_link(void)
{
    int res;

    struct test_thread_data thread_data[2];

    thread_data[INITIATOR].context = thread_data[TARGET].context = cut_get_current_test_context();
    thread_data[INITIATOR].device = devices[INITIATOR];
    thread_data[TARGET].device = devices[TARGET];

    if ((res = pthread_create(&(threads[TARGET]), NULL, target_thread, &thread_data[TARGET])))
        cut_fail("pthread_create() returned %d", res);
    if ((res = pthread_create(&(threads[INITIATOR]), NULL, initiator_thread, &thread_data[INITIATOR])))
        cut_fail("pthread_create() returned %d", res);

    signal(SIGINT, abort_test_by_keypress);

    if ((res = pthread_join(threads[INITIATOR], (void *) &result[INITIATOR])))
        cut_fail("pthread_join() returned %d", res);
    if ((res = pthread_join(threads[TARGET], (void *) &result[TARGET])))
        cut_fail("pthread_join() returned %d", res);

    cut_assert_equal_int(0, result[INITIATOR], cut_message("Unexpected initiator return code"));
    cut_assert_equal_int(0, result[TARGET], cut_message("Unexpected target return code"));
}
Example #3
0
static void
mb_assert_res_pool_valid(mb_res_pool_t *pool)
{
    mb_res_pool_cell_t *cell;
    GHashTable *table;

    table = g_hash_table_new(g_direct_hash, g_direct_equal);

    if (pool->nr_avail == 0) {
        return;
    }
    cell = pool->head;
    do {
        // check duplication of cell->data
        if (g_hash_table_lookup(table, cell->data) != NULL) {
            cut_fail("duplicated pointer in the pool");
        }
        g_hash_table_insert(table, cell->data, cell->data);

        // check NULL
        if (cell->data == NULL) {
            cut_fail("NULL pointer in the pool");
        }

        cell = cell->next;
    } while(cell != pool->tail->next);
}
Example #4
0
void
cut_setup(void)
{
  if (llcp_init())
    cut_fail("llcp_init() failed");

  sem_cutter = sem_open(sem_cutter_name, O_CREAT | O_EXCL,  0666, 0);
  if (sem_cutter == SEM_FAILED)
    cut_fail("sem_open() failed");
}
Example #5
0
/**
 * print_timer() 関数テスト
 *
 * @return なし
 */
void
test_print_timer(void)
{
    unsigned int t = 0, time = 0; /* タイマ用変数 */
    int fd = -1;                  /* ファイルディスクリプタ */
    int retval = 0;               /* 戻り値 */
    char actual[BUF_SIZE] = {0};  /* 実際の文字列 */
    const char expected[] =       /* 期待する文字列 */
        "time of time: [0-9]+\\.[0-9]+\\[msec\\]";

    start_timer(&t);
    time = stop_timer(&t);
    fd = pipe_fd(STDERR_FILENO);
    if (fd < 0) {
        cut_error("pipe_fd=%d(%d)", fd, errno);
        return;
    }

    print_timer(time);

    retval = read(fd, actual, sizeof(actual));
    if (retval < 0) {
        cut_fail("read=%d(%d)", fd, errno);
        goto error_handler;
    }
    dbglog("actual=%s", actual);

    cut_assert_match(expected, actual,
                     cut_message("expected=%s actual=%s",
                                 expected, actual));

error_handler:
    close_fd(&fd, NULL);
}
Example #6
0
static void 
do_test (gint         index,
	 const gchar *text, 
	 gint         max_len,
	 gint         offset,
	 gboolean     valid)
{
  const gchar *end;
  gboolean result;
  
  result = g_utf8_validate (text, max_len, &end);

  if (result != valid || end - text != offset)
    {
      GString *str;
      const gchar *p;

      str = g_string_new (0);
      for (p = text; *p; p++)
	g_string_append_printf (str, "\\x%02hhx", *p);

      cut_fail ("%d: g_utf8_validate (\"%s\", %d) failed, "
	        "expected %s %d, got %s %d\n",
	        index,
	        str->str, max_len, 
	        valid ? "TRUE" : "FALSE", offset,
	        result ? "TRUE" : "FALSE", (gint) (end - text));
      g_string_free (str, FALSE);
    }
}
Example #7
0
Int cont_eam(USES_REGS1) {
  if (eam_am((PredEntry *)0x2))
    return (TRUE);
  else {
    cut_fail();
    return (FALSE);
  }
}
Example #8
0
void
cut_setup(void)
{
  if (llcp_init())
    cut_fail("llcp_init() failed");

  /* Void service is never called */
  void_service(NULL);
}
Example #9
0
static void test_query_all_evt_cb(history_gluon_stream_event_t *evt)
{
	if (evt->type == HISTORY_GLUON_STREAM_EVENT_END) {
		query_all_evt_called_end = 1;
		query_all_evt_result = evt->result;
	} else if (evt->type == HISTORY_GLUON_STREAM_EVENT_GOT_DATA) {
		g_tree_insert(g_gtree, make_sample_key(evt->data), evt->data);
		evt->flags |= HISTORY_GLUON_STREAM_EVENT_FLAG_DONT_FREE_DATA;
	}
	else 
		cut_fail("Unknown type: %d", evt->type);
}
Example #10
0
static gpointer
fail (gpointer data)
{
    CutTestContext *context = data;
    gint i;

    cut_set_current_test_context(context);

    for (i = 0; i < 10; i++) {
        cut_fail("failed in thread");
    }

    return NULL;
}
Example #11
0
static void
mb_check_will_not_free(void)
{
    GList *candidates;
    for(candidates = will_not_free_list;
        candidates != NULL;
        candidates = candidates->next) {
        will_free_cell_t *cell = (will_free_cell_t *) candidates->data;

        if (g_list_find(freed_list, cell->ptr) != NULL) {
            cut_fail("%s (addr %p) should not be freed (asserted at %s:%d)",
                     cell->exp,
                     cell->ptr,
                     cell->fname,
                     cell->lineno);
        }
    }
}
Example #12
0
/* query less/greater */
static void
assert_add_and_query_less_greater(uint64_t id, void (*add_samples_fn)(void),
                                  history_gluon_data_t *samples,
                                  history_gluon_query_t query_type)
{
	assert_make_context_delete_add_samples(id, add_samples_fn);

	// query
	int idx = 1;
	struct timespec ts;
	set_mean_ts(&samples[idx].ts, &samples[idx+1].ts, &ts);

	// query
	assert_query(id, &ts, query_type, HGL_SUCCESS);

	int exp_idx = idx;
	if (query_type == HISTORY_GLUON_QUERY_TYPE_LESS_DATA)
		exp_idx = idx;
	else if (query_type ==  HISTORY_GLUON_QUERY_TYPE_GREATER_DATA)
		exp_idx = idx + 1;
	else
		cut_fail("Unknown query_type: %d", query_type);
	assert_equal_hgl_data(&samples[exp_idx], g_data);
}
Example #13
0
/// @memberof between/3
static Int
init_between( USES_REGS1 )
{
  Term t1 = Deref(ARG1);
  Term t2 = Deref(ARG2);

  if (IsVarTerm(t1)) {
    Yap_EvalError(INSTANTIATION_ERROR, t1, "between/3");
    return FALSE;
  }
  if (IsVarTerm(t2)) {
    Yap_EvalError(INSTANTIATION_ERROR, t1, "between/3");
    return FALSE;
  }
  if (!IsIntegerTerm(t1) && 
      !IsBigIntTerm(t1)) {
    Yap_EvalError(TYPE_ERROR_INTEGER, t1, "between/3");
    return FALSE;
  }
  if (!IsIntegerTerm(t2) && 
      !IsBigIntTerm(t2) &&
      t2 != MkAtomTerm(AtomInf) &&
      t2 != MkAtomTerm(AtomInfinity)) {
    Yap_EvalError(TYPE_ERROR_INTEGER, t2, "between/3");
    return FALSE;
  }
  if (IsIntegerTerm(t1) && IsIntegerTerm(t2)) {
    Int i1 = IntegerOfTerm(t1);
    Int i2 = IntegerOfTerm(t2);
    Term t3;

    t3 = Deref(ARG3);
    if (!IsVarTerm(t3)) {
      if (!IsIntegerTerm(t3)) {
	if (!IsBigIntTerm(t3)) {
	  Yap_EvalError(TYPE_ERROR_INTEGER, t3, "between/3");
	  return FALSE;
	}
	cut_fail();
      } else {
	Int i3 = IntegerOfTerm(t3);
	if (i3 >= i1 && i3 <= i2)
	  cut_succeed();
	cut_fail();
      }
    }
    if (i1 > i2) cut_fail();
    if (i1 == i2) {
      Yap_unify(ARG3, t1);
      cut_succeed();
    }
  } else if (IsIntegerTerm(t1) && IsAtomTerm(t2)) {
    Int i1 = IntegerOfTerm(t1);
    Term t3;

    t3 = Deref(ARG3);
    if (!IsVarTerm(t3)) {
      if (!IsIntegerTerm(t3)) {
	if (!IsBigIntTerm(t3)) {
	  Yap_EvalError(TYPE_ERROR_INTEGER, t3, "between/3");
	  return FALSE;
	}
	cut_fail();
      } else {
	Int i3 = IntegerOfTerm(t3);
	if (i3 >= i1)
	  cut_succeed();
	cut_fail();
      }
    }
  } else {
    Term t3 = Deref(ARG3);
    Int cmp;

    if (!IsVarTerm(t3)) {
      if (!IsIntegerTerm(t3) && !IsBigIntTerm(t3)) {
	Yap_EvalError(TYPE_ERROR_INTEGER, t3, "between/3");
	return FALSE;
      }
      if (Yap_acmp(t3, t1 PASS_REGS) >= 0 && Yap_acmp(t2,t3 PASS_REGS) >= 0 && P != FAILCODE)
	cut_succeed();
      cut_fail();
    }
    cmp = Yap_acmp(t1, t2 PASS_REGS);
    if (cmp > 0) cut_fail();
    if (cmp == 0) {
      Yap_unify(ARG3, t1);
      cut_succeed();
    }
  }
  EXTRA_CBACK_ARG(3,1) = t1;
  EXTRA_CBACK_ARG(3,2) = t2;
  return cont_between( PASS_REGS1 );
}
Example #14
0
static void
construct_object(gconstpointer data, grn_builtin_type type, grn_obj *object)
{
  switch (type) {
  case GRN_DB_VOID:
    GRN_VOID_INIT(object);
    break;
  case GRN_DB_BOOL:
    GRN_BOOL_INIT(object, 0);
    GRN_BOOL_SET(&context, object, gcut_data_get_boolean(data, "value"));
    break;
  case GRN_DB_INT8:
    GRN_INT8_INIT(object, 0);
    GRN_INT8_SET(&context, object, gcut_data_get_int(data, "value"));
    break;
  case GRN_DB_UINT8:
    GRN_UINT8_INIT(object, 0);
    GRN_UINT8_SET(&context, object, gcut_data_get_uint(data, "value"));
    break;
  case GRN_DB_INT16:
    GRN_INT16_INIT(object, 0);
    GRN_INT16_SET(&context, object, gcut_data_get_int(data, "value"));
    break;
  case GRN_DB_UINT16:
    GRN_UINT16_INIT(object, 0);
    GRN_UINT16_SET(&context, object, gcut_data_get_uint(data, "value"));
    break;
  case GRN_DB_INT32:
    GRN_INT32_INIT(object, 0);
    GRN_INT32_SET(&context, object, gcut_data_get_int(data, "value"));
    break;
  case GRN_DB_UINT32:
    GRN_UINT32_INIT(object, 0);
    GRN_UINT32_SET(&context, object, gcut_data_get_uint(data, "value"));
    break;
  case GRN_DB_INT64:
    GRN_INT64_INIT(object, 0);
    GRN_INT64_SET(&context, object, gcut_data_get_int64(data, "value"));
    break;
  case GRN_DB_UINT64:
    GRN_UINT64_INIT(object, 0);
    GRN_UINT64_SET(&context, object, gcut_data_get_uint64(data, "value"));
    break;
  case GRN_DB_FLOAT:
    GRN_FLOAT_INIT(object, 0);
    GRN_FLOAT_SET(&context, object, gcut_data_get_double(data, "value"));
    break;
  case GRN_DB_TIME:
    GRN_TIME_INIT(object, 0);
    GRN_TIME_SET(&context, object, gcut_data_get_int64(data, "value"));
    break;
  case GRN_DB_SHORT_TEXT:
    GRN_SHORT_TEXT_INIT(object, 0);
    GRN_TEXT_SETS(&context, object, gcut_data_get_string(data, "value"));
    break;
  case GRN_DB_TEXT:
    GRN_TEXT_INIT(object, 0);
    GRN_TEXT_SETS(&context, object, gcut_data_get_string(data, "value"));
    break;
  case GRN_DB_LONG_TEXT:
    GRN_LONG_TEXT_INIT(object, 0);
    GRN_TEXT_SETS(&context, object, gcut_data_get_string(data, "value"));
    break;
  case GRN_DB_TOKYO_GEO_POINT:
    GRN_TOKYO_GEO_POINT_INIT(object, 0);
    GRN_GEO_POINT_SET(&context, object,
                      gcut_data_get_int(data, "latitude"),
                      gcut_data_get_int(data, "longitude"));
    break;
  case GRN_DB_WGS84_GEO_POINT:
    GRN_WGS84_GEO_POINT_INIT(object, 0);
    GRN_GEO_POINT_SET(&context, object,
                      gcut_data_get_int(data, "latitude"),
                      gcut_data_get_int(data, "longitude"));
    break;
  default:
    cut_fail("unknown type: %d", type);
    break;
  }
}
Example #15
0
static void
cut_poppler_assert_equal_property_helper (const gchar *title,
                                          const gchar *format,
                                          const gchar *author,
                                          const gchar *subject,
                                          const gchar *keywords,
                                          GTime creation_date,
                                          GTime mod_date,
                                          const gchar *creator,
                                          const gchar *producer,
                                          const gchar *linearized,
                                          PopplerPageMode mode,
                                          PopplerPageLayout layout,
                                          PopplerViewerPreferences viewer_preferences,
                                          PopplerPermissions permissions,
                                          PopplerDocument *document)
{
  gchar *actual_title;
  gchar *actual_format;
  gchar *actual_author;
  gchar *actual_subject;
  gchar *actual_keywords;
  GTime actual_creation_date;
  GTime actual_mod_date;
  gchar *actual_creator;
  gchar *actual_producer;
  gchar *actual_linearized;
  PopplerPageMode actual_mode;
  PopplerPageLayout actual_layout;
  PopplerViewerPreferences actual_viewer_preferences;
  PopplerPermissions actual_permissions;

  g_object_get (document,
		"title", &actual_title,
		"format", &actual_format,
		"author", &actual_author,
		"subject", &actual_subject,
		"keywords", &actual_keywords,
		"creation-date", &actual_creation_date,
		"mod-date", &actual_mod_date,
		"creator", &actual_creator,
		"producer", &actual_producer,
		"linearized", &actual_linearized,
		"page-mode", &actual_mode,
		"page-layout", &actual_layout,
		"viewer-preferences", &actual_viewer_preferences,
		"permissions", &actual_permissions,
		NULL);

  if (cut_equal_string (title, actual_title) &&
      cut_equal_string (format, actual_format) &&
      cut_equal_string (author, actual_author) &&
      cut_equal_string (subject, actual_subject) &&
      cut_equal_string (keywords, actual_keywords) &&
      creation_date == actual_creation_date &&
      mod_date == actual_mod_date &&
      cut_equal_string (creator, actual_creator) &&
      cut_equal_string (producer, actual_producer) &&
      cut_equal_string (linearized, actual_linearized) &&
      mode == actual_mode &&
      layout == actual_layout &&
      viewer_preferences == actual_viewer_preferences &&
      permissions == actual_permissions)
    {
      cut_test_pass ();
    }
  else
    {
      gchar *inspected_expected;
      gchar *inspected_actual;
      const gchar *message;

      inspected_expected = inspect_property (title,
                                             format,
                                             author,
                                             subject,
                                             keywords,
                                             creation_date,
                                             mod_date,
                                             creator,
                                             producer,
                                             linearized,
                                             mode,
                                             layout,
                                             viewer_preferences,
                                             permissions);
      inspected_actual = inspect_property (actual_title,
                                           actual_format,
                                           actual_author,
                                           actual_subject,
                                           actual_keywords,
                                           actual_creation_date,
                                           actual_mod_date,
                                           actual_creator,
                                           actual_producer,
                                           actual_linearized,
                                           actual_mode,
                                           actual_layout,
                                           actual_viewer_preferences,
                                           actual_permissions);
      message = cut_take_printf ("expected: <%s>\n"
                                 "  actual: <%s>",
                                 inspected_expected, inspected_actual);
      message = cut_append_diff (message, inspected_expected, inspected_actual);
      g_free (inspected_expected);
      g_free (inspected_actual);
      cut_fail ("%s", message);
    }
}
Example #16
0
static void
cut_assert_always_fail (void)
{
    cut_fail("always fail");
}
void
test_mifare_desfire_ev1_3des (void)
{
    int res;

    /* Select the master application */
    res = mifare_desfire_select_application (tag, NULL);
    cut_assert_success ("mifare_desfire_select_application()");

    /* Get version information */
    struct mifare_desfire_version_info version_info;
    res = mifare_desfire_get_version (tag, &version_info);
    cut_assert_success ("mifare_desfire_get_version()");

     mifare_desfire_auto_authenticate (tag, 0);

    /*
     * This unit test change key settings to more restrictive ones, so reset
     * them to factory defaults in case the previous run failed unexpectedly.
     */
    res = mifare_desfire_change_key_settings (tag, 0xF);
    cut_assert_success ("mifare_desfire_change_key_settings()");
    res = mifare_desfire_change_key_settings (tag, 0xF);
    cut_assert_success ("mifare_desfire_change_key_settings()");

    /* Change master key to AES */
    MifareDESFireKey key = mifare_desfire_3des_key_new_with_version (key_data_3des);
    mifare_desfire_change_key (tag, 0, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");

    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    /* Wipeout the card */
    res = mifare_desfire_format_picc (tag);
    cut_assert_success ("mifare_desfire_format_picc()");


    /* Create 3 applications */
    res = mifare_desfire_select_application (tag, NULL);
    cut_assert_success ("mifare_desfire_select_application()");

    key = mifare_desfire_3des_key_new_with_version (key_data_3des);
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    uint8_t key_version;
    res = mifare_desfire_get_key_version (tag, 0, &key_version);
    cut_assert_success ("mifare_desfire_get_key_version()");
    cut_assert_equal_int (0x55, 0x55, cut_message ("Wrong key_version value."));

    uint32_t size;
    res = mifare_desfire_free_mem (tag, &size);
    cut_assert_success ("mifare_desfire_free_mem()");

    MifareDESFireAID aid_a = mifare_desfire_aid_new (0x00AAAAAA);
    //cut_assert_not_null (aid_a, cut_message ("Cannot allocate AID"));
    res = mifare_desfire_create_application (tag, aid_a, 0xFF, 0);
    cut_assert_success ("mifare_desfire_create_application()");

    MifareDESFireAID aid_b = mifare_desfire_aid_new (0x00BBBBBB);
    cut_assert_not_null (aid_b, cut_message ("Cannot allocate AID"));
    res = mifare_desfire_create_application (tag, aid_b, 0xEF, 6);
    cut_assert_success ("mifare_desfire_create_application()");

    MifareDESFireAID aid_c = mifare_desfire_aid_new (0x00CCCCCC);
    cut_assert_not_null (aid_c, cut_message ("Cannot allocate AID"));
    res = mifare_desfire_create_application (tag, aid_c, 0xC2, 14);
    cut_assert_success ("mifare_desfire_create_application()");

    // Ensure we can find the created applications
    MifareDESFireAID *aids = NULL;
    size_t aid_count;
    res = mifare_desfire_get_application_ids (tag, &aids, &aid_count);
    cut_assert_success ("mifare_desfire_get_application_ids()");
    cut_assert_equal_int (3, aid_count, cut_message ("Wrong application count"));
    mifare_desfire_free_application_ids (aids);

    // Create files in the application A
    res = mifare_desfire_select_application (tag, aid_a);
    cut_assert_success ("mifare_desfire_select_application()");

    uint8_t std_data_file_id = 15;

    res = mifare_desfire_create_std_data_file (tag, std_data_file_id, MDCM_PLAIN, 0xEEEE, 100);
    cut_assert_success ("mifare_desfire_create_std_data_file()");

    res = mifare_desfire_create_backup_data_file (tag, 5, MDCM_PLAIN, 0xEEEE, 64);
    cut_assert_success ("mifare_desfire_create_backup_data_file()");

    res = mifare_desfire_create_value_file (tag, 4, MDCM_PLAIN, 0xEEEE, 0, 1000, 0, 0);
    cut_assert_success ("mifare_desfire_create_value_file()");

    res = mifare_desfire_create_cyclic_record_file (tag, 0, MDCM_PLAIN, 0xEEEE, 4, 10);
    cut_assert_success ("mifare_desfire_create_cyclic_record_file()");

    // Write some data in the standard data file
    res = mifare_desfire_write_data (tag, std_data_file_id, 0, 30, (uint8_t *)"Some data to write to the card");
    cut_assert_success ("mifare_desfire_write_data()");
    cut_assert_equal_int (30, res, cut_message ("Wrong number of bytes writen"));

    res = mifare_desfire_write_data (tag, std_data_file_id, 34, 22, (uint8_t *)"Another block of data.");
    cut_assert_success ("mifare_desfire_write_data()");
    cut_assert_equal_int (22, res, cut_message ("Wrong number of bytes writen"));

    // Make the file read-only
    res = mifare_desfire_change_file_settings (tag, std_data_file_id, MDCM_PLAIN, 0xEFFF);
    cut_assert_success ("mifare_desfire_change_file_settings()");

    // Read a part of the file
    uint8_t buffer[120];
    res = mifare_desfire_read_data (tag, std_data_file_id, 10, 50, &buffer);
    cut_assert_success ("mifare_desfire_read_data()");
    cut_assert_equal_int (50, res, cut_message ("Wrong number of bytes read"));
    cut_assert_equal_memory ("to write to the card\0\0\0\0Another block of data.\0\0\0\0", 50, buffer, 50, cut_message ("Wrong data"));

    // Read all the file at once
    res = mifare_desfire_read_data (tag, std_data_file_id, 0, 0, &buffer);
    cut_assert_success ("mifare_desfire_read_data()");
    cut_assert_equal_int (100, res, cut_message ("Wrong number of bytes read"));
    cut_assert_equal_memory ("Some data to write to the"
			     " card\0\0\0\0Another block of"
			     " data.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
			     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 100, buffer, 100, cut_message ("Wrong data"));

    // Try to overwrute the file
    res = mifare_desfire_write_data (tag, std_data_file_id, 20, 5, (char *)"Test!");
    cut_assert_equal_int (-1, res, cut_message ("Wrong return value"));
    cut_assert_equal_int (PERMISSION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error"));

    int32_t expected_value = 0;
    for (int transaction = 0; transaction < 15; transaction++) {

	char data_buffer[3];

	sprintf (data_buffer, "%02d", transaction);

	// Write to the backup file
	res = mifare_desfire_write_data (tag, 5, 3*transaction, 3, data_buffer);
	cut_assert_success ("mifare_desfire_write_data()");

	// Manipulate the value file
	res = mifare_desfire_credit (tag, 4, 100);
	cut_assert_success ("mifare_desfire_credit()");

	res = mifare_desfire_debit (tag, 4, 97);
	cut_assert_success ("mifare_desfire_debit()");

	// Write to the cyclic record file
	res = mifare_desfire_write_record (tag, 0, 2, 2, data_buffer);
	cut_assert_success ("mifare_desfire_write_record()");

	// Overwrite the cyclic record file
	res = mifare_desfire_write_record (tag, 0, 0, 2, (char *)"r.");
	cut_assert_success("mifare_desfire_write_record()");

	// Ensure that no content was changed yet
	char ref_buffer[64];
	memset (ref_buffer, 0, sizeof (ref_buffer));
	for (int n = 0; n < transaction; n++) {
	    sprintf (ref_buffer + 3 * n, "%02d", n);
	}

	res = mifare_desfire_read_data (tag, 5, 0, 0, buffer);
	cut_assert_success ("mifare_desfire_read_data()");
	cut_assert_equal_int (64, res, cut_message ("Wrong number of bytes read"));
	cut_assert_equal_memory (buffer, 64, ref_buffer, 64, cut_message ("Wrong data"));

	int32_t value;
	res = mifare_desfire_get_value (tag, 4, &value);
	cut_assert_success ("mifare_desfire_get_value()");
	cut_assert_equal_int (expected_value, value, cut_message ("Wrong value"));

	// Reading records from an empty file would abort the transaction
	if (0 != transaction) {
	    // Get the latest record
	    res = mifare_desfire_read_records (tag, 0, 0, 1, buffer);
	    cut_assert_success ("mifare_desfire_read_records()");
	    sprintf (ref_buffer, "r.%02d", transaction);
	    cut_assert_not_equal_memory (ref_buffer, 4, buffer, res, cut_message ("Wrong data"));
	}

	// Commit !
	res = mifare_desfire_commit_transaction (tag);
	cut_assert_success ("mifare_desfire_commit_transaction()");


	res = mifare_desfire_read_data (tag, 5, 3*transaction, 3, buffer);
	cut_assert_success ("mifare_desfire_read_data()");
	cut_assert_equal_memory (data_buffer, 3, buffer, res, cut_message ("Wrong data"));

	expected_value += 3;

	res = mifare_desfire_get_value (tag, 4, &value);
	cut_assert_success ("mifare_desfire_get_value()");
	cut_assert_equal_int (expected_value, value, cut_message ("Wrong value"));

	res = mifare_desfire_read_records (tag, 0, 0, 1, buffer);
	cut_assert_success ("mifare_desfire_read_records()");
	sprintf (ref_buffer, "r.%02d", transaction);
	cut_assert_equal_memory (ref_buffer, 4, buffer, res, cut_message ("Wrong data"));
    }

    // Ensure limited credit is disabled
    res = mifare_desfire_limited_credit (tag, 4, 20);
    cut_assert_equal_int (-1, res, cut_message ("mifare_desfire_limited_credit() should fail"));

    // Get all files
    uint8_t *files;
    size_t file_count;
    res = mifare_desfire_get_file_ids (tag, &files, &file_count);
    cut_assert_success ("mifare_desfire_get_file_ids()");
    cut_assert_equal_int (4, file_count, cut_message ("Wrong number of files"));

    for (size_t i=0; i<file_count;i++) {
	if ((files[i] != 0) && (files[i] != 4) &&
	    (files[i] != 5) && (files[i] != 15)) {
	    cut_fail ("File %d should not exist.", files[i]);
	}

	struct mifare_desfire_file_settings settings;
	res = mifare_desfire_get_file_settings (tag, files[i], &settings);
	cut_assert_success ("mifare_desfire_get_file_settings()");

	switch (files[i]) {
	case 0:
	    cut_assert_equal_int (MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP, settings.file_type, cut_message ("Wrong file type"));
	    cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings"));
	    cut_assert_equal_int (4, settings.settings.linear_record_file.record_size, cut_message ("Wrong record size"));
	    cut_assert_equal_int (10, settings.settings.linear_record_file.max_number_of_records, cut_message ("Wrong max number of records"));
	    cut_assert_equal_int (9, settings.settings.linear_record_file.current_number_of_records, cut_message ("Wrong current number of records"));
	    break;
	case 4:
	    cut_assert_equal_int (MDFT_VALUE_FILE_WITH_BACKUP, settings.file_type, cut_message ("Wrong file type"));
	    cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings"));

	    cut_assert_equal_int (0, settings.settings.value_file.lower_limit, cut_message ("Wrong lower limit"));
	    cut_assert_equal_int (1000, settings.settings.value_file.upper_limit, cut_message ("Wrong upper limit"));
	    cut_assert_equal_int (97, settings.settings.value_file.limited_credit_value, cut_message ("Wrong limited_credit value"));
	    cut_assert_equal_int (0, settings.settings.value_file.limited_credit_enabled, cut_message ("Wrong limited_credit enable state"));
	    break;
	case 5:
	    cut_assert_equal_int (MDFT_BACKUP_DATA_FILE, settings.file_type, cut_message ("Wrong file type"));
	    cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings"));
	    cut_assert_equal_int (64, settings.settings.standard_file.file_size, cut_message ("Wrong file size"));
	    break;
	case 15:
	    cut_assert_equal_int (MDFT_STANDARD_DATA_FILE, settings.file_type, cut_message ("Wrong file type"));
	    cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings"));
	    cut_assert_equal_int (100, settings.settings.standard_file.file_size, cut_message ("Wrong file size"));
	    break;
	default:
	    cut_fail ("Wow!  Cosmic ray!");
	}

	res = mifare_desfire_delete_file (tag, files[i]);
	cut_assert_success ("mifare_desfire_delete_file()");
    }

    free (files);

    // All files should have been removed
    res = mifare_desfire_get_file_ids (tag, &files, &file_count);
    cut_assert_success ("mifare_desfire_get_file_ids()");
    cut_assert_equal_int (0, file_count, cut_message ("Wrong number of files"));

    // Delete application A
    res = mifare_desfire_select_application (tag, 0);
    cut_assert_success ("mifare_desfire_select_application()");

    key = mifare_desfire_3des_key_new (key_data_3des);
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    res = mifare_desfire_delete_application (tag, aid_a);
    cut_assert_success ("mifare_desfire_delete_application()");

    // Ensure application A was deleted
    res = mifare_desfire_get_application_ids (tag, &aids, &aid_count);
    cut_assert_success ("mifare_desfire_get_application_ids()");
    cut_assert_equal_int (2, aid_count, cut_message ("Wrong application count"));
    mifare_desfire_free_application_ids (aids);

    // Change application B keys
    res = mifare_desfire_select_application (tag, aid_b);
    cut_assert_success ("mifare_desfire_select_application()");

    key = mifare_desfire_des_key_new (key_data_null);
    res = mifare_desfire_authenticate (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate()");
    mifare_desfire_key_free (key);

    // Use an AES application master key
    key = mifare_desfire_3des_key_new_with_version ((uint8_t *) "App.B Master Key12345678");
    res = mifare_desfire_change_key (tag, 0, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (key);

    /* Authenticate with the new master key */
    key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Master Key12345678");
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    res = mifare_desfire_get_key_version (tag, 0, &key_version);
    cut_assert_success ("mifare_desfire_get_key_version()");
    cut_assert_equal_int (0x83, key_version, cut_message ("Wrong key version"));

    /* Change key #1 */
    key = mifare_desfire_des_key_new (key_data_null);
    res = mifare_desfire_authenticate (tag, 1, key);
    cut_assert_success ("mifare_desfire_authenticate()");
    mifare_desfire_key_free (key);

    key = mifare_desfire_3des_key_new ((uint8_t *) "Another AES key!12345678");
    res = mifare_desfire_change_key (tag, 1, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (key);

    /* Change key #5 */
    key = mifare_desfire_des_key_new (key_data_null);
    res = mifare_desfire_authenticate (tag, 5, key);
    cut_assert_success ("mifare_desfire_authenticate()");
    mifare_desfire_key_free (key);

    key = mifare_desfire_3des_key_new ((uint8_t *) "B's Chg Keys Key12345678");
    res = mifare_desfire_change_key (tag, 5, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (key);

    /* Set key #5 as the change key */
    key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Master Key12345678");
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    res = mifare_desfire_change_key_settings (tag, 0x5F);
    cut_assert_success ("mifare_desfire_change_key_settings()");

    uint8_t key_settings;
    uint8_t max_keys;
    res = mifare_desfire_get_key_settings (tag, &key_settings, &max_keys);
    cut_assert_success ("mifare_desfire_get_key_settings()");

    cut_assert_equal_int (0x5F, key_settings, cut_message ("Wrong key settings"));
    cut_assert_equal_int (6, max_keys, cut_message ("Wrong maximum number of keys"));

    /* Change key #1 to #4 using the three key procedure. */
    key = mifare_desfire_3des_key_new ((uint8_t *) "B's Chg Keys Key12345678");
    res = mifare_desfire_authenticate_iso (tag, 5, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #1.   12345678");
    MifareDESFireKey key1 = mifare_desfire_3des_key_new ((uint8_t *) "Another AES key!12345678");
    res = mifare_desfire_change_key (tag, 1, key, key1);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (key);
    mifare_desfire_key_free (key1);
    key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #2..  12345678");
    res = mifare_desfire_change_key (tag, 2, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (key);
    key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #3... 12345678");
    res = mifare_desfire_change_key (tag, 3, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (key);
    key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #4....12345678");
    res = mifare_desfire_change_key (tag, 4, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (key);

    std_data_file_id--;

    res = mifare_desfire_create_std_data_file (tag, std_data_file_id, MDCM_PLAIN, 0x1234, 100);
    cut_assert_success ("mifare_desfire_create_std_data_file()");
    expected_value = -1000000;
    res = mifare_desfire_create_value_file (tag, 4, 0, 0x1324, -987654321, -1000, expected_value, 1);
    cut_assert_success ("mifare_desfire_create_value_file()");
    res = mifare_desfire_create_linear_record_file (tag, 1, 0, 0x1324, 25, 4);

    int nr = 0;
    for (int transaction = 0; transaction < 7; transaction++) {
	uint8_t cs = transaction % 3;
	if (cs == 2) cs++;

	key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #4....12345678");
	res = mifare_desfire_authenticate_iso (tag, 4, key);
	cut_assert_success ("mifare_desfire_authenticate_iso()");
	mifare_desfire_key_free (key);

	res = mifare_desfire_change_file_settings (tag, std_data_file_id, cs, 0x1234);
	cut_assert_success ("mifare_desfire_change_file_settings()");
	res = mifare_desfire_change_file_settings (tag, 4, cs, 0x1324);
	cut_assert_success ("mifare_desfire_change_file_settings()");
	res = mifare_desfire_change_file_settings (tag, 1, cs, 0x1324);
	cut_assert_success ("mifare_desfire_change_file_settings()");

	// Authenticate witht he write key
	key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #2..  12345678");
	res = mifare_desfire_authenticate_iso (tag, 2, key);
	cut_assert_success ("mifare_desfire_authenticate_iso()");
	mifare_desfire_key_free (key);

	char data_buffer[100];
	char data_buffer2[100];
	char data_buffer3[100];
	for (int i = 0; i < 100; i++)
	    data_buffer[i] = transaction + i;

	res = mifare_desfire_write_data (tag, std_data_file_id, 0, 100, data_buffer);
	cut_assert_success ("mifare_desfire_write_data()");

	sprintf (data_buffer2, "Transaction #%d", transaction);

	res = mifare_desfire_write_data (tag, std_data_file_id, 5, strlen (data_buffer2), data_buffer2);
	cut_assert_success ("mifare_desfire_write_data()");

	memcpy (data_buffer + 5, data_buffer2, strlen (data_buffer2));

	// Write to the linear record.  When it's full, erase it and restart.
	for (int i = 0; i < 2; i++) {
	    if ((transaction % 2 == 1) && (i == 1)) {
		res = mifare_desfire_clear_record_file (tag, 1);
		cut_assert_success ("mifare_desfire_clear_record_file()");

		sprintf (data_buffer3, "Test invalid write");
		res = mifare_desfire_write_record (tag, 1, 0, strlen (data_buffer3), data_buffer3);
		cut_assert_equal_int (-1, res, cut_message ("error code"));
		cut_assert_equal_int (PERMISSION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("PICC error"));

		// The previous failure has aborted the transaction, so
		// re-authenticate, then clear record again.
		key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #2..  12345678");
		res = mifare_desfire_authenticate_iso (tag, 2, key);
		cut_assert_success ("mifare_desfire_authenticate_iso");
		mifare_desfire_key_free (key);

		res = mifare_desfire_clear_record_file (tag, 1);
		cut_assert_success ("mifare_desfire_clear_record_file()");

		res = mifare_desfire_commit_transaction (tag);
		cut_assert_success ("mifare_desfire_commit_transaction()");
		nr = 0;
	    }

	    res = mifare_desfire_write_record (tag, 1, 0, 25, "0123456789012345678901234");
	    cut_assert_success ("mifare_desfire_write_record()");

	    res = mifare_desfire_write_record (tag, 1, 5, strlen (data_buffer2), data_buffer2);
	    cut_assert_success ("mifare_desfire_write_record()");
	}
	nr++;

	// Modify the value file
	res = mifare_desfire_debit (tag, 4, 1300);
	cut_assert_success ("mifare_desfire_debit()");
	expected_value -= 1300;
	res = mifare_desfire_credit (tag, 4, 20);
	cut_assert_success ("mifare_desfire_credit()");
	expected_value += 20;
	res = mifare_desfire_debit (tag, 4, 1700);
	cut_assert_success ("mifare_desfire_debit()");
	expected_value -= 1700;

	// Commit
	res = mifare_desfire_commit_transaction (tag);
	cut_assert_success ("mifare_desfire_commit_transaction()");

	// Refund the whole debited amount
	res = mifare_desfire_limited_credit (tag, 4, 3000);
	cut_assert_success ("mifare_desfire_limited_credit()");
	expected_value += 3000;

	// Commit
	res = mifare_desfire_commit_transaction (tag);
	cut_assert_success ("mifare_desfire_commit_transaction()");

	// Authenticate with the key that allows reading
	key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #1.   12345678");
	res = mifare_desfire_authenticate_iso (tag, 1, key);
	cut_assert_success ("mifare_desfire_authenticate_iso()");
	mifare_desfire_key_free (key);

	// Read first half of the file
	res = mifare_desfire_read_data (tag, std_data_file_id, 0, 50, data_buffer3);
	cut_assert_success ("mifare_desfire_read_data()");
	cut_assert_equal_int (50, res, cut_message ("length"));
	cut_assert_equal_memory (data_buffer, 50, data_buffer3, res, cut_message ("data"));

	// Read second half of the file
	res = mifare_desfire_read_data (tag, std_data_file_id, 50, 0, data_buffer3);
	cut_assert_success ("mifare_desfire_read_data()");
	cut_assert_equal_int (50, res, cut_message ("length"));
	cut_assert_equal_memory (data_buffer + 50, 50, data_buffer3, res, cut_message ("data"));

	// Get the value file current balance
	int32_t value;
	res = mifare_desfire_get_value (tag, 4, &value);
	cut_assert_success ("mifare_desfire_get_value()");
	cut_assert_equal_int (expected_value, value, cut_message ("value"));

	// Get the number of records in the linear record file
	struct mifare_desfire_file_settings settings;
	res = mifare_desfire_get_file_settings (tag, 1, &settings);
	cut_assert_success ("mifare_desfire_get_file_settings()");
	cut_assert_equal_int (MDFT_LINEAR_RECORD_FILE_WITH_BACKUP, settings.file_type, cut_message ("settings"));
	cut_assert_equal_int (nr, settings.settings.linear_record_file.current_number_of_records, cut_message ("settings"));

	// Read the oldest record
	res = mifare_desfire_read_records (tag, 1, nr - 1, 1, data_buffer3);
	cut_assert_success ("mifare_desfire_read_records()");
	cut_assert_equal_int (25, res, cut_message ("length"));

	sprintf (data_buffer, "0123456789012345678901234");
	sprintf (data_buffer2, "Transaction #%d", transaction - nr + 1);
	memcpy ((uint8_t *)data_buffer + 5, data_buffer2, strlen (data_buffer2));
	cut_assert_equal_memory (data_buffer, strlen (data_buffer), data_buffer3, res, cut_message ("data"));

	// Read all records
	res = mifare_desfire_read_records (tag, 1, 0, 0, data_buffer3);
	cut_assert_success ("mifare_desfire_read_records()");
	cut_assert_equal_int (25 * nr, res, cut_message ("length"));
    }

    res = mifare_desfire_get_file_ids (tag, &files, &file_count);
    cut_assert_success ("mifare_desfire_get_file_ids");
    cut_assert_equal_int (3, file_count, cut_message ("count"));

    for (size_t i = 0; i < file_count; i++) {
	struct mifare_desfire_file_settings settings;
	res = mifare_desfire_get_file_settings (tag, files[i], &settings);
	cut_assert_success ("mifare_desfire_get_file_settings()");

	switch (files[i]) {
	case 1:
	    cut_assert_equal_int (MDFT_LINEAR_RECORD_FILE_WITH_BACKUP, settings.file_type, cut_message ("type"));
	    cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("cs"));
	    cut_assert_equal_int (0x1324, settings.access_rights, cut_message ("access_rights"));
	    cut_assert_equal_int (25, settings.settings.linear_record_file.record_size, cut_message ("record_size"));
	    cut_assert_equal_int (4, settings.settings.linear_record_file.max_number_of_records, cut_message ("max_number_of_records"));
	    cut_assert_equal_int (2, settings.settings.linear_record_file.current_number_of_records, cut_message ("current_number_of_records"));
	    break;
	case 4:
	    cut_assert_equal_int (MDFT_VALUE_FILE_WITH_BACKUP , settings.file_type, cut_message ("type"));
	    cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("cs"));
	    cut_assert_equal_int (0x1324, settings.access_rights, cut_message ("access_rights"));
	    cut_assert_equal_int (-987654321, settings.settings.value_file.lower_limit, cut_message ("lower_limit"));
	    cut_assert_equal_int (-1000, settings.settings.value_file.upper_limit, cut_message ("upper_limit"));
	    cut_assert_equal_int (0, settings.settings.value_file.limited_credit_value, cut_message ("limited_credit_value"));
	    cut_assert_equal_int (1, settings.settings.value_file.limited_credit_enabled, cut_message ("limited_credit_enabled"));
	    break;
	case 14: /* std_data_file_id */
	    cut_assert_equal_int (MDFT_STANDARD_DATA_FILE, settings.file_type, cut_message ("type"));
	    cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("cs"));
	    cut_assert_equal_int (0x1234, settings.access_rights, cut_message ("access_rights"));
	    cut_assert_equal_int (100, settings.settings.standard_file.file_size, cut_message ("size"));
	    break;
	default:
	    cut_fail ("file_no");

	}

	res = mifare_desfire_delete_file (tag, files[i]);
	cut_assert_success ("mifare_desfire_delete_file()");
    }
    free (files);

    // Check there are no files anymore
    res = mifare_desfire_get_file_ids (tag, &files, &file_count);
    cut_assert_success ("mifare_desfire_get_file_ids");
    cut_assert_equal_int (0, file_count, cut_message ("count"));

    /* Delete application B */
    key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Master Key12345678");
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    res = mifare_desfire_delete_application (tag, aid_b);
    cut_assert_success ("mifare_desfire_delete_application()");

    res = mifare_desfire_get_application_ids (tag, &aids, &aid_count);
    cut_assert_success ("mifare_desfire_get_application_ids()");
    cut_assert_equal_int (1, aid_count, cut_message ("Wrong AID count"));
    mifare_desfire_free_application_ids (aids);

    /* Tests using application C */

    res = mifare_desfire_select_application (tag, aid_c);
    cut_assert_success ("mifare_desfire_select_application()");

    key = mifare_desfire_des_key_new (key_data_null);
    res = mifare_desfire_authenticate (tag, 12, key);
    cut_assert_success ("mifare_desfire_authenticate()");

    MifareDESFireKey new_key = mifare_desfire_3des_key_new ((uint8_t *)"App.C Key #1.   12345678");
    res = mifare_desfire_change_key (tag, 1, new_key, key);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (new_key);

    new_key = mifare_desfire_3des_key_new ((uint8_t *)"App.C Key #2..  12345678");
    res = mifare_desfire_change_key (tag, 2, new_key, key);
    cut_assert_success ("mifare_desfire_change_key()");
    mifare_desfire_key_free (new_key);

    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);


    res = mifare_desfire_create_cyclic_record_file (tag, 6, MDCM_PLAIN, 0x12E0, 100, 22);
    cut_assert_success ("mifare_desfire_create_cyclic_record_file()");

    for (int transaction = 0; transaction < 50; transaction++) {
	char data_buffer[100];
	char read_buffer[100];

	uint8_t cs = transaction % 3;
	if (cs == 2) cs++;

	key = mifare_desfire_des_key_new (key_data_null);
	res = mifare_desfire_authenticate (tag, 0, key);
	cut_assert_success ("mifare_desfire_authenticate()");
	mifare_desfire_key_free (key);

	res = mifare_desfire_change_file_settings (tag, 6, cs, 0x12E0);
	cut_assert_success ("mifare_desfire_change_file_settings()");

	if (transaction & 4) {
	    key = mifare_desfire_3des_key_new ((uint8_t *) "App.C Key #2..  12345678");
	    res = mifare_desfire_authenticate_iso (tag, 2, key);
	    cut_assert_success ("mifare_desfire_authenticate_iso()");
	    mifare_desfire_key_free (key);
	} else {
	    cs = 0;
	}

	memset (data_buffer, '_', 100);
	data_buffer[0]  = transaction;
	data_buffer[99] = transaction;
	sprintf (data_buffer + 5, " Transaction #%d ", transaction);
	res = mifare_desfire_write_record (tag, 6, 0, 100, data_buffer);
	cut_assert_success ("mifare_desfire_write_record()");

	if (transaction & 4) {
	    key = mifare_desfire_3des_key_new ((uint8_t *) "App.C Key #1.   12345678");
	    res = mifare_desfire_authenticate_iso (tag, 1, key);
	    cut_assert_success ("mifare_desfire_authenticate_iso()");
	    mifare_desfire_key_free (key);
	}

	if (transaction % 7 == 0) {
	    res = mifare_desfire_abort_transaction (tag);
	    cut_assert_success ("mifare_desfire_abort_transaction()");

	    ssize_t n = mifare_desfire_read_records (tag, 6, 0, 1, read_buffer);
	    if (transaction == 0) {
		cut_assert_equal_int (-1, n, cut_message ("Wrong return value"));
	    } else {
		cut_assert_equal_int (100, n, cut_message ("Wrong return value"));
		cut_assert_not_equal_memory (data_buffer, sizeof (data_buffer), read_buffer, sizeof (read_buffer), cut_message ("Wrong data"));
	    }
	} else {
	    res = mifare_desfire_commit_transaction (tag);
	    cut_assert_success ("mifare_desfire_commit_transaction()");

	    ssize_t n = mifare_desfire_read_records (tag, 6, 0, 1, read_buffer);
	    cut_assert_equal_int (100, n, cut_message ("Wrong return value"));
	    cut_assert_equal_memory (data_buffer, sizeof (data_buffer), read_buffer, sizeof (read_buffer), cut_message ("Wrong data"));
	}
    }

    // Read each record
    key = mifare_desfire_3des_key_new ((uint8_t *) "App.C Key #1.   12345678");
    res = mifare_desfire_authenticate_iso (tag, 1, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    int t = 49;
    for (int i = 0; i < 22; i++) {
	char data_buffer[100];
	char ref_data_buffer[100];

	if (0 == (t % 7))
	    t--;

	memset (ref_data_buffer, '_', 100);
	ref_data_buffer[0]  = t;
	ref_data_buffer[99] = t;
	sprintf (ref_data_buffer + 5, " Transaction #%d ", t);
	res = mifare_desfire_read_records (tag, 6, i, 1, data_buffer);
	if (i == 21) {
	    cut_assert_equal_int (-1, res, cut_message ("return value"));
	} else {
	    cut_assert_success ("mifare_desfire_read_records()");
	    cut_assert_equal_memory (ref_data_buffer, 100, data_buffer, res, cut_message ("data"));
	}

	t--;
    }

    /*
     * Change master key settings to require master key authentication for all
     * card operations.  Only allow to revert this.
     */

    res = mifare_desfire_select_application (tag, 0);
    cut_assert_success ("mifare_desfire_select_application()");

    key = mifare_desfire_3des_key_new (key_data_3des);
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    res = mifare_desfire_change_key_settings (tag, 0x08);
    cut_assert_success ("mifare_desfire_change_key_settings()");

    /* Clear authentication */
    res = mifare_desfire_select_application (tag, 0);
    cut_assert_success ("mifare_desfire_select_application()");

    /* We should not be able to list applications now */
    res = mifare_desfire_get_application_ids (tag, &aids, &aid_count);
    cut_assert_equal_int (-1, res, cut_message ("Wrong return value"));
    cut_assert_equal_int (AUTHENTICATION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error"));

    /* Deleting an application should not be possible */
    res = mifare_desfire_delete_application (tag, aid_c);
    cut_assert_equal_int (-1, res, cut_message ("Wrong return value"));
    cut_assert_equal_int (AUTHENTICATION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error"));

    /* Creating an application should also be forbidden */
    MifareDESFireAID aid_d = mifare_desfire_aid_new (0x00DDDDDD);
    res = mifare_desfire_create_application (tag, aid_d, 0xEF, 0);
    cut_assert_equal_int (-1, res, cut_message ("Wrong return value"));
    cut_assert_equal_int (AUTHENTICATION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error"));

    /*
     * Now we retry authenticated with the master key.
     */
    key = mifare_desfire_3des_key_new (key_data_3des);
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    /* We should be able to list applications again */
    res = mifare_desfire_get_application_ids (tag, &aids, &aid_count);
    cut_assert_success ("mifare_desfire_get_application_ids()");
    cut_assert_equal_int (1, aid_count, cut_message ("Wrong AID count"));
    mifare_desfire_free_application_ids (aids);

    /* Deleting an application should be possible again */
    res = mifare_desfire_delete_application (tag, aid_c);
    cut_assert_success ("mifare_desfire_delete_application()");

    /* Creating an application should also be possible */
    res = mifare_desfire_create_application (tag, aid_d, 0xEF, 0);
    cut_assert_success ("mifare_desfire_create_application()");

    /* Revert master key settings to default */
    res = mifare_desfire_change_key_settings (tag, 0xF);
    cut_assert_success ("mifare_desfire_change_key_settings()");

    /* Change the master key back to the default one */
    key = mifare_desfire_3des_key_new (key_data_3des);
    res = mifare_desfire_authenticate_iso (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate_iso()");
    mifare_desfire_key_free (key);

    key = mifare_desfire_des_key_new_with_version (key_data_null);
    res = mifare_desfire_change_key (tag, 0, key, NULL);
    cut_assert_success ("mifare_desfire_change_key()");

    /*
     * Delete everything from the card
     */

    res = mifare_desfire_authenticate (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate()");
    mifare_desfire_key_free (key);

    res = mifare_desfire_format_picc (tag);
    cut_assert_success ("mifare_desfire_format_picc()");

    free (aid_a);
    free (aid_b);
    free (aid_c);
    free (aid_d);
}
static void
stub_failure_test (void)
{
    MARK_FAIL(cut_fail("This test should fail"));
}