asn1set__SWIdent swIdent[] = { { asn1set__SWIdent__printableString, { "Terisa Demo Merchant Software v.beta1" } } }; extern asn__any *mer_dn; /* Merchant DN */ extern asn__any *pay_dn; /* Payment Gateway DN */ int merchant_reads_PInitReq_writes_PInitRes() { set_app_ctx app_ctx = 0; /* thread-specific global data */ log_ctx history = 0; /* past-transaction info */ cache_ctx msg_cache = 0; /* per-transaction data */ int msg_type; /* asn1set__Message__... */ PInitReq pInitReq = 0; /* SET message subtype */ PInitRes pInitRes = 0; /* SET message subtype */ set_msg request = 0; /* SET message base type */ set_msg response = 0; /* SET message base type */ asn1set__XID xid; /* transaction ID */ int status; /* return value */ io_ctx stdin_ctx; /* stdin input stream */ io_ctx stdout_ctx; /* stdout output stream */ /* Open the log, which contains information about previous * messages that have been processed. The log is used * primarily to detect repeated/replayed messages. */ status = create_log_ctx_db(&history, "merchant.log"); assert(status == NO_ERROR); /* Create the thread-specific context, setting the default software * identifier to "swIdent", and using the 8-character password * "password" to unlock the certificate database. No callback * function is specified. */ status = create_set_app_ctx(&app_ctx, swIdent, history, "password", 8, 0, 0); assert(status == NO_ERROR); /* Create a blank SET message and associate the heap "standard_heap" * with the message. All memory allocated and placed into * "request" by receive_set_msg() or decode_set_msg() * will be allocated out of "standard_heap", which is a globally-defined * alloc_ctx that performs no garbage collection. */ status = create_set_msg(&request, app_ctx, standard_heap); assert(status == NO_ERROR); /* Attached the standard I/O input stream "stdin" to the * io_ctx "stdin_ctx" */ status = create_stdio_ctx(&stdin_ctx, stdin); assert(status == NO_ERROR); /* Get the PInitReq message from the stdin, which is specified using * "stdin_ctx", an io_ctx connected to stdin. After the call * to receive_set_msg(), "msg_type" contains the type of the * message that was read from the input stream. */ status = receive_set_msg(request, app_ctx, stdin_ctx, &msg_type); assert(status == NO_ERROR); assert(msg_type == asn1set__Message__pInitReq); /* Decode and decrypt the message. */ status = decode_set_msg(request, app_ctx); assert(status == NO_ERROR); /* The PInitReq message does not contain a transaction ID (XID), * so the merchant must create the XID */ status = create_new_XID(&xid); assert(status == NO_ERROR); /* Open the per-transaction cache. Since the PInitReq message is * probably the first message of the transaction that the merchant * has received or sent, the following call will create a new * cache with the supplied name, which in this case uses the * transaction ID (XID). Moreover, this XID is then inserted into * the cache to be later used by SETREF. */ status = create_cache_ctx_db(&msg_cache, xid2filename(&xid)); assert(status == NO_ERROR); status = CACHE_put(msg_cache, STATE_XID, &xid); assert(status == NO_ERROR); /* Verify the request message. After the message has been verified, * the contents of the message can safely be used. Note, all memory * allocated by verify_set_msg() that is passed back is allocated out * of "standard_heap". */ status = verify_set_msg(request, app_ctx, &msg_cache); assert(status == NO_ERROR); /* After a call to verify_set_msg(), "request" can be cast to * its specific SET message subtype, in this case PInitReq. If * request is not a PInitReq message, then 0 is returned. */ pInitReq = safe_cast_PInitReq(request); assert(pInitReq != 0); /* insert GATEWAY_DN into cache, based on BrandID in PInitReq */ status = CACHE_put(msg_cache, STATE_GATEWAY_DN, pay_dn); assert(status == NO_ERROR); /* Create a blank SET message and associate the heap "standard_heap" * with the message. All memory allocated and placed into * "response" by make_set_msg() or send_set_msg() will be * allocated out of standard_heap, which is a globally-defined alloc_ctx * that performs no garbage collection. */ status = create_set_msg(&response, app_ctx, standard_heap); assert(status == NO_ERROR); /* Build the PInitRes message by calling make_set_msg(). Previous * state in this transaction (which at this point only consists of * the previous PInitReq message and XID) is obtained using * "msg_cache". Protocol layer data is inserted into the message * by make_set_msg(). */ msg_type = asn1set__Message__pInitRes; status = make_set_msg(response, app_ctx, &msg_cache, msg_type); assert(status == NO_ERROR); /* After a call to make_set_msg(), "response" can be cast to * its specific SET message subtype, in this case PInitRes. */ pInitRes = safe_cast_PInitRes(response); assert(pInitRes != 0); /* Application-layer data is inserted into the message. */ pInitRes->pInitResData.transIDs.pReqDate = time(0); pInitRes->merchantSignatureCID = mer_dn; /* Attached the standard I/O output stream "stdout" to the * io_ctx "stdout_ctx" */ status = create_stdio_ctx(&stdout_ctx, stdout); assert(status == NO_ERROR); /* The PInitRes message is sent to the output stream stdout, * which is specified using stdout_ctx, an io_ctx connected * to stdout. */ status = send_set_msg(response, app_ctx, &msg_cache, stdout_ctx); assert(status == NO_ERROR); /* Perform the cleanup by deleting any contexts which had been * created. If another message is going to be processed, even * one that is part of another transaction, then app_ctx can * be used to process that message, rather than being deleted. * The log is closed here, but as long as the application * doesn't quit, the log could remain open because there is * normally only a single, global log. */ status = IO_delete(&stdin_ctx); assert(status == NO_ERROR); status = IO_delete(&stdout_ctx); assert(status == NO_ERROR); status = CACHE_delete(&msg_cache); assert(status == NO_ERROR); status = delete_set_msg(&response); assert(status == NO_ERROR); status = delete_set_msg(&request); assert(status == NO_ERROR); status = delete_set_app_ctx(&app_ctx); assert(status == NO_ERROR); status = LOG_delete(&history); assert(status == NO_ERROR); return NO_ERROR; }
Copyright © 1996, 1997, Visa International Service Association and MasterCard International Incorporated
All Rights Reserved.