// create a new card with the given inital_amount as the balance and add it to the card_list // success: SUCCESS // failure: ERRNO_MP_ALLOC, ERRNO_MP_LIST_PUSH int card_create_and_add_to_list(card_t ** card, list_t * card_list, uint32_t initial_amount) { // create card RET_ON_FAIL(card_create(card, card_list->count, initial_amount)); // add card to list RET_ON_FAIL(card_add_to_list(*card, card_list)); return SUCCESS; }
// create a new transaction and add it to the transaction_list // success: SUCCESS, // failure: ERRNO_MP_ALLOC, ERRNO_MP_LIST_PUSH int transaction_create_and_add_to_list(transaction_t ** tr, list_t * tr_list, packet_head_t * pkt_hdr_ptr, uint32_t card_id) { RET_ON_FAIL(transaction_create(tr, tr_list->count, pkt_hdr_ptr)); // update transaction with new card id (*tr)->card_id = card_id; RET_ON_FAIL(transaction_add_to_list(*tr, tr_list)); return SUCCESS; }
// remove transaction node from transaction list, and dealloc // the data pointer to by transaction->details should be reset and deallocated before calling this function // success: SUCCESS // failure: ERRNO_MP_ALLOC, ERRNO_MP_LIST_RM int transaction_destroy(list_t * tr_list, uint32_t transaction_id) { //rm transaction node from list and get ptr to transaction node node_t * tr_node = NULL; RET_ON_FAIL(transaction_rm_from_list(&tr_node, tr_list, transaction_id)); transaction_t * tr = (transaction_t *)tr_node->data; // deallocate the memory used by the transaction if(SUCCESS != deallocate((void *)tr, sizeof(transaction_t))) {return ERRNO_MP_ALLOC;} //destroy node RET_ON_FAIL(node_destroy(tr_node)); return SUCCESS; }
// check the given transaction id to verify there is an associated transaction in the OPS state // having the same op_code // return associated transaction via tr // success: SUCCESS // failure: ERRNO_MP_NOT_FOUND, ERRNO_MP_INVALID_CARD, ERRNO_MP_NO_OPS int transaction_ops_done(transaction_t ** tr, packet_head_t * pkt_hdr_ptr, list_t * tr_list) { RET_ON_FAIL(transaction_get(tr, pkt_hdr_ptr->transaction_id, pkt_hdr_ptr->op_code, tr_list)); if(pkt_hdr_ptr->card_id != (*tr)->card_id) {return ERRNO_MP_INVALID_CARD;} if((*tr)->state != OPS) {return ERRNO_MP_NO_OPS;} return SUCCESS; }
// find the transaction in tr_list that was a purchase with purchase_id and return it in ref_tr // success: SUCCESS // failure: ERRNO_MP_NOT_FOUND int transaction_get_and_verify_purchase_id(list_t * tr_list, packet_data_refund_t * pdr, transaction_t ** ref_tr) { RET_ON_FAIL(transaction_get(ref_tr, pdr->transaction_id, PURCHASE, tr_list)); // verify purchase_id packet_data_purchase_t * p = (packet_data_purchase_t *)(*ref_tr)->details; if(p->purchase_id != pdr->purchase_id) {return ERRNO_MP_NOT_FOUND;} return SUCCESS; }
// look up the balance of the card with card_id and write it into balance. // success: SUCCESS // failure: ERRNO_MP_NOT_FOUND int card_get_balance(uint32_t card_id, list_t * card_list, uint32_t * balance) { // find card having card_id card_t * card = NULL; RET_ON_FAIL(card_get(&card, card_id, card_list)); // return card balance *balance = card->balance; return SUCCESS; }
// create new packet header with values from transaction. // and send packet header // success: SUCCESS // failure: ERRNO_MP_ALLOC int packet_from_transaction_and_send(transaction_t * tr, uint32_t auth_code) { packet_head_t * new_pkt_header = NULL; RET_ON_FAIL(packet_from_transaction(tr, &new_pkt_header, auth_code)); // send packet_header to client send((char *)new_pkt_header, sizeof(packet_head_t)); // free memory for new_pkt_header. if(SUCCESS != deallocate((void *)new_pkt_header, sizeof(packet_head_t))) {return ERRNO_MP_ALLOC;} return SUCCESS; }
// refund amount from purchase transaction to card in card_list // success: SUCCESS // failure: ERRNO_MP_NOT_FOUND, ERRNO_MP_REFUND_FULL int card_refund(uint32_t card_id, list_t * card_list, transaction_t * tr) { // verify card_id matches that used in the transaction if(card_id != tr->card_id) { RET_ON_FAIL(ERRNO_MP_NOT_FOUND); } // find card having card_id card_t * card = NULL; RET_ON_FAIL(card_get(&card, card_id, card_list)); // get purchase out of transaction packet_data_purchase_t * p = (packet_data_purchase_t *)tr->details; // if balance will wrap around, return error. if(card->balance + p->cost >= p->cost) { // add purchase amount to card balance card->balance += p->cost; } else { return ERRNO_MP_REFUND_FULL; } return SUCCESS; }
// add amount to the balance of card with id card_id in card_list // success: SUCCESS // failure: ERRNO_MP_NOT_FOUND, ERRNO_MP_RECHARGE_FULL int card_recharge(uint32_t card_id, list_t * card_list, uint32_t amount) { // find card having card_id card_t * card = NULL; RET_ON_FAIL(card_get(&card, card_id, card_list)); // if balance will wrap around, return error. if(card->balance + amount >= amount) { // update card balance card->balance += amount; } else { return ERRNO_MP_RECHARGE_FULL; } return SUCCESS; }
// subtract amount from the balance of card with id card_id in card_list // success: SUCCESS // failure: ERRNO_MP_NOT_FOUND, ERRNO_MP_PURCHASE_ISF int card_purchase(uint32_t card_id, list_t * card_list, uint32_t amount) { int ret = 0; // find card card_t * card = NULL; RET_ON_FAIL(card_get(&card, card_id, card_list)); // update card balance if sufficient funds if(card->balance >= amount) { card->balance -= amount; } else { return ERRNO_MP_PURCHASE_ISF; } return SUCCESS; }