/*
* Copyright (c) 2019 Clementine Computing LLC.
*
* This file is part of PopuFare.
*
* PopuFare is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PopuFare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with PopuFare. If not, see .
*
*/
#ifndef _PASSDB_H
#define _PASSDB_H
#include
#include
#include "../common/common_defs.h"
#include "ruleparam_db.h"
#include "byte_access.h"
typedef unsigned long long seq_t;
typedef unsigned long long logical_card_id_t;
//#define PASSDB_CONSISTENCY_CHECK
#define FN_SZ 1024
//#define RIDER_ONE_CRED_SIZE 27
//#define RIDER_TWO_CRED_SIZE ( sizeof(seq_t) + sizeof(logical_card_id_t) +
// sizeof(unsigned char) + sizeof(unsigned long long) +
// sizeof(unsigned char) + sizeof (unsigned long) + sizeof(unsigned long) +
// sizeof(unsigned short int) )
// This record is only used for transport
// of information. On disk storage needs to be
// done through the helper functions.
//
typedef struct rider_record_slim_two_cred_struct
{
seq_t seq;
logical_card_id_t id;
unsigned long long magstripe;
unsigned long rfid_site;
unsigned long rfid_val;
unsigned short int rule_param_bucket_id;
unsigned char rfid_code;
unsigned char magstripe_code;
} rider_record_slim_two_cred;
//#define RIDER_TWO_CRED_SIZE 36
//#define RIDER_ONE_CRED_SIZE ( sizeof(seq_t) + sizeof(logical_card_id_t) +
// sizeof(unsigned char) + sizeof(unsigned long long) +
// sizeof (unsigned short int) )
// This record is only used for transport
// of information. On disk storage needs to be
// done through the helper functions.
//
typedef struct rider_record_slim_one_cred
{
seq_t seq;
logical_card_id_t id;
unsigned long long credential;
unsigned short int rule_param_bucket_id;
unsigned char code;
} rider_record_slim_one_cred;
//THIS STRUCTURE MUST BE A POWER OF 2 BYTES IN SIZE
//NOTE: this was the old entry format for the old database.
// rider_records are still used, but serve only as transport
// structures to hold information and for the 'spillover'
// records. The main on-disk storage now is the rider one
// cred and rider two cred structures above, which are not
// powers of two in size.
// This rider_record struct is also used to transport
// information about the card and provide a consistent
// interface to the rest of the ecosystem.
//
typedef struct rider_record_struct
{
seq_t seq; //sequence number
logical_card_id_t id; //rider ID
char magstripe_value[CREDENTIAL_LEN];
char rfid_value[CREDENTIAL_LEN];
char rule_name[RULENAME_LEN];
char rule_param[PARAM_LEN];
} rider_record;
typedef struct rule_pass_param_bucket_struct
{
unsigned int rule_param_bucket_id;
char rule_name[RULENAME_LEN];
char rule_param[PARAM_LEN];
} rule_pass_param_bucket;
// 0 <= idx < INDEX_MIDPOINT -> single credential (either rfid or mag only)
// INDEX_MIDPOINT <= idx < 2*INDEX_MIDPOINT -> double credential (both rfid + mag)
//
// idx >= 2*INDEX_MIDPOINT in spillover
//
// Each 'bank' is a block of X one credential, two credential or spillover packed
// structures. X is read from the passdb.conf file (see passdb_slim_config.[ch]).
//
typedef struct rider_node_struct
{
int idx;
struct rider_node_struct *next;
} rider_node;
typedef struct passdb_slim_context_struct
{
void **rider_one_cred_bank;
void **rider_two_cred_bank;
void **rider_spillover_bank;
// Helper vairables to keep count of number of one and two credit
// credentials in all of the banks.
//
// heap of active and free rider indexes
// (indexed into rider_one_cred and rider_two_cred)
// simple linear linked lists
//
rider_node *activelist;
rider_node *freelist_one_cred;
rider_node *freelist_two_cred;
rider_node *freelist_spillover;
char **one_cred_db_bank_fn;
char **two_cred_db_bank_fn;
char **spillover_db_bank_fn;
// current number of banks for each database type
//
int n_one_cred;
int n_two_cred;
int n_spillover;
int n_one_cred_bank;
int n_two_cred_bank;
int n_spillover_bank;
int n_one_cred_bank_size;
int n_two_cred_bank_size;
int n_spillover_bank_size;
int n_one_cred_max_bank;
int n_two_cred_max_bank;
int n_spillover_max_bank;
int hash_modulus;
// hashes of logical_card_id, mag and rf
// for quick lookup
//
rider_node **logical_card_id_hash;
rider_node **rider_mag_hash;
rider_node **rider_rf_hash;
seq_t seq;
// THESE ARE USED IF MMAP IS DETERMINED TO BE BROKEN...
// it's broken...
int mmap_broken;
int num_free;
int num_active;
int *passes_one_cred_bank_fd;
int *passes_two_cred_bank_fd;
int *passes_spillover_bank_fd;
size_t rider_one_file_size;
size_t rider_two_file_size;
size_t rider_spillover_file_size;
size_t rider_one_file_bank_size;
size_t rider_two_file_bank_size;
size_t rider_spillover_file_bank_size;
char diagnostic_str[128];
ruleparam_db_ctx *ruleparam_db;
char *ruleparam_db_fn;
char *one_cred_db_base_fn;
char *two_cred_db_base_fn;
char *spillover_db_base_fn;
char *db_fn_suffix;
float high_watermark_threshold;
float low_watermark_threshold;
} passdb_slim_context;
typedef struct passdb_slim_config_t {
int hash_modulus;
int n_one_cred_bank;
int n_two_cred_bank;
int n_spillover_bank;
int n_one_cred_bank_size;
int n_two_cred_bank_size;
int n_spillover_bank_size;
int n_one_cred_max_bank;
int n_two_cred_max_bank;
int n_spillover_max_bank;
char *one_cred_db_base_fn;
char *two_cred_db_base_fn;
char *spillover_db_base_fn;
char *db_fn_suffix;
char *ruleparam_db_fn;
size_t rider_one_file_bank_size;
size_t rider_two_file_bank_size;
size_t rider_spillover_file_bank_size;
float high_watermark_threshold;
float low_watermark_threshold;
} passdb_slim_config;
//--------------------------
int format_new_passdb( char *, int, long );
int format_new_passdbs();
int attach_to_passdb(passdb_slim_context *ctx);
int detach_from_passdb(passdb_slim_context *ctx);
int delete_rider(passdb_slim_context *ctx, rider_record *rec, int sync);
int update_rider(passdb_slim_context *ctx, rider_record *rec, int sync);
void sync_all_riders(passdb_slim_context *ctx);
void dump_hashes(passdb_slim_context *ctx);
int find_mag_in_hash(passdb_slim_context *ctx, char *mag);
int find_rf_in_hash(passdb_slim_context *ctx, char *rfid);
void populate_one_cred_rider_record( rider_record_slim_one_cred *, int, void *);
void populate_two_cred_rider_record( rider_record_slim_two_cred *, int, void *);
void populate_spillover_rider_record( rider_record *, int, void *);
int make_rider_record_from_rider_one_cred( passdb_slim_context *ctx, rider_record *rr, rider_record_slim_one_cred *rr1 );
int make_rider_record_from_rider_two_cred( passdb_slim_context *ctx, rider_record *rr, rider_record_slim_two_cred *rr2 );
int make_rider_record_from_rider_spillover( passdb_slim_context *, rider_record *, rider_record *);
void make_rider_record( passdb_slim_context *ctx, rider_record *rr, int idx );
int passdb_slim_get_cred_bank_and_pos( passdb_slim_context *ctx, int *bank, int *pos, int idx );
int passdb_slim_consistency_check( passdb_slim_context *ctx );
// config file functions
//
void passdb_slim_copy_config( passdb_slim_config *, passdb_slim_context *);
int save_config( passdb_slim_config *, char *);
int read_config( passdb_slim_config *, char *);
int init_context_from_config( passdb_slim_context *, char *);
int make_default_config( char *);
// DEBUGGING
//
void passdb_slim_dump( passdb_slim_context * );
#endif