/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/*                                                                        */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* (C) COPYRIGHT International Business Machines Corp. 1996,2019          */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

static char *sccsid = "@(#)93   1.32   src/rsct/pgs/samples/sample_callbacks.c, gssamples, rsct_rady, rady2035a 7/12/19 17:24:01";

#if !defined(_HAGSD_COPYRIGHT_H)
#define _HAGSD_COPYRIGHT_H
static char copyright[] = "Licensed Materials - Property of IBM\n\
(C) COPYRIGHT International Business Machines Corp. 1996,2001.\n\
All Rights Reserved.\n\
US Government Users Restricted Rights - Use, duplication or \n\
disclosure restricted by GSA ADP Schedule Contract with IBM Corp.\n";
#endif

/*********************************************************************/
/*
 * Name:  sample_callbacks.c
 *
 * This program provides the set of callback and utility functions used
 * by the "sample_test" program.
 *
 * Components:
 *   sample_callbacks.c - this module, provides the definitions for the
 *      callback functions used for the groups created by this program.
 *
 *   sample_test.c - contains the main() function, supports interaction
 *      with the user, and most calls to the Group Services interfaces.
 *
 *   sample_utility.c - provides the definitions for the utility functions
 *      used by the sample_test program.
 *
 *   sample_callbacks.h - declarations for the callback functions
 *      contained in sample_callbacks.c.
 *
 *   sample_utility.h - declarations for the utility functions contained
 *      in sample_utility.c
 *
 * The information here assumes that you are familiar with the information
 * presented in the IBM RSCT Group Services Programming Guide and Reference
 * manual.
 *
 * This program is provided for illustrative purposes only, and is not
 * intended to be an authoritative description of the "best" methods to
 * use when writing a Group Services application.  It is intended to
 * demonstrate the various interfaces in a relatively verbose manner,
 * and to allow you to relatively easily manipulate groups and their
 * members.
 *
 * To this end, various aspects of this program (in particular its
 * handling of screen input and output) are neither robust nor
 * foolproof.  Therefore, you should take care when giving input to
 * this program.
 */
/*********************************************************************/

/*********************************************************************/
/*
 * Please refer to sample_test.c for information about building and
 * using the sample_test program.
 */
/*********************************************************************/

/*********************************************************************/
/*
 * Callback functions.
 *
 * The bulk of an application's interaction with Group Services will
 * be through asynchronous messaging.  When a message is received by
 * the application from Group Services, the application must call the
 * ha_gs_dispatch() function (please refer to the IBM RSCT Group
 * Services Programming Guide and Reference manual for full details.)
 *
 * ha_gs_dispatch() will in turn read the message(s) from the socket
 * connecting the application to Group Services, and for each message
 * received will execute the appropriate callback function.  The
 * callback function will be given a "notification" (again, refer to
 * the IBM RSCT Group Services Programming Guide and Reference manual
 * for a full description of each notification.)  It is the duty of
 * the callback function to examine the notification and to take
 * appropriate actions.
 *
 * There are three general classes of callback functions:
 *  1) general callback functions, specified by a client when it
 *      initializes its connection (via ha_gs_init()) with Group
 *      Services.
 *  2) group-specific provider callbacks, specified by a client
 *      when it joins a group (via ha_gs_join()).
 *  3) group-specific subscriber callbacks, specified by a client
 *      when it subscribes to a group (via ha_gs_subscribe()).
 *
 * 1) General callback functions.  These callback functions are
 *      called when responsiveness notifications, delayed error
 *      notifications and query-response notifications arrive from
 *      Group Services.  Each process connected to Group Services
 *      has one set of these callback functions defined.
 *
 *    In this module, these callback functions are called:
 *      a) responsive_cb() -- to handle responsiveness notifications.
 *      b) delayed_error_cb() -- to handle delayed error notifications.
 *      c) query_cb() -- to handle query response notifications.
 *      d) domain_control_cb() -- to handle domain control notifications.
 *
 * 2) Group-specific provider callbacks.  When a Group Services client
 *      is joining a group, it must specify a set of callback functions
 *      to be used when notifications related to that group arrive from
 *      Group Services.  Note that it is allowable to either:
 *      - use the same set of callback functions for all groups that a
 *        client joins, or,
 *      - specify a different set for each for each group.
 *
 *    This module actually uses both methods.  A set of "pre-defined"
 *      are defined (see sample_test.c) and for these, each group has
 *      its own set of callback functions.  In addition, a "build"
 *      command ('b', again, see sample_test.c) is provided that allows
 *      the user to interactively define and join one or more groups.
 *      For all such "user-defined" groups, the same set of callback
 *      functions is shared.
 *
 *    The callback functions are named as follows.  Each has a base name,
 *      to which is appended an integer, which differentiates the set of
 *      names for each group.  In this list, the integer is represented
 *      by 'N':
 *      a) n_phase_cbN() - handles n-phase protocol notifications.
 *      b) approved_cbN() - handles protocol approved notifications.
 *      c) rejected_cbN() - handles protocol rejected notifications.
 *      d) announce_cbN() - handles group announcement notifications.
 *      e) merge_cbN() - handles group merge notifications.
 *
 *    Each pre-defined group uses the following integer suffix:
 *      theSourceGroup - 0 (zero, e.g., n_phase_cb0()).
 *      OnePhaseJoin -  1 (one, e.g., n_phase_cb1()).
 *      theTargetGroup - 2 (two, e.g., n_phase_cb2()).
 *      theLonelyGroup - 3 (three, e.g., n_phase_cb3()).
 *      ifFirstIWin - 4 (four, e.g., n_phase_cb4()).
 *      SourceOrNot - 5 (five, e.g., n_phase_cb5()).
 *      ChainGang - 6 (six, e.g., n_phase_cb6()).
 *
 *    The user-defined group(s) all share the callback functions with
 *      integer suffix 7 (seven, e.g., n_phase_cb7()).
 *
 * 3) Group-specific subscription callbacks.  When a Group Services 
 *      client is subscribing to a group, it must specify a callback
 *      function to be executed when a subscription notification 
 *      applying to that group has been received from Group Services.
 *      As described for group-specific provider callbacks, different
 *      callback functions may be defined for each group subscription,
 *      or a single callback function can handle all subscriptions.
 *
 *    So, similarly to the provider callbacks, this module defines a
 *      different subscription callback function for each "pre-defined"
 *      group, using the same integer suffix scheme as above with the
 *      base name "subscribe_cbN()" (e.g., a subscription to
 *      "theSourceGroup" would use 'subscribe_cb0().)  All subscriptions
 *      to any user-defined groups share 'subscribe_cb7().
 *
 *    In addition, this program supports subscriptions to the various
 *      Group Services "System Membership" groups, as well as to any
 *      arbitrary groups.  (Refer to the IBM RSCT Group Services
 *      Programming Guide and Reference manual for a discussion of the
 *      System Membership groups.)  For these subscriptions, the
 *      following set of callback functions is used:
 *      a) subscribe_cb_HostMbr() -- is used if you subscribe to the
 *          Group Services System Membership "Host Membership" group.
 *      b) subscribe_cb_EnetMbr() -- is used if you subscribe to the
 *          Group Services System Membership "Ethernet Adapter Membership"
 *          group.
 *      c) subscribe_cb_CssMbr() -- is used if you subscribe to the
 *          Group Services System Membership "High Performance Switch
 *          Adapter Membership" group.
 *      d) subscribe_cb_Pick() -- is used for all subscriptions to any
 *          other groups in the system to which you subscribe, if these
 *          groups are not part of the sample_test set of groups.
 *
 * The file sample_callbacks.h contains the prototypes for all of the
 * callback functions.
 */
/*********************************************************************/

/*********************************************************************/
/*
 * Include "standard" system files.  Note that pthread.h must be the
 * first file included, if it is to be included (see the standard AIX
 * documentation for more information about AIX thread support.)
 */
/*********************************************************************/

#ifdef _THREAD_SAFE                     /* begin _THREAD_SAFE */
#include <pthread.h>
#endif                                  /* end _THREAD_SAFE */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include <memory.h>
#ifndef __linux__
#include <time.h>
#else
#include <sys/time.h>
#endif

/*********************************************************************/
/*
 * Include the Group Services declarations file.
 */
/*********************************************************************/

#include <ha_gs.h>

/*********************************************************************/
/*
 * Include the set of declarations for callbacks for this program.
 */
/*********************************************************************/

#include "sample_callbacks.h"

/*********************************************************************/
/*
 * Include the set of declarations for utility functions for this program.
 */
/*********************************************************************/

#include "sample_utility.h"

#define MSGLEN    1000000
/**********************************************************************/
/*
 * This first set of callbacks (delayed errors, responsiveness, and query
 * response) are specified on the ha_gs_init() call.  These deal with
 * notifications that apply to the Group Services client process, although
 * delayed error notifications may also apply to a specific provider or
 * subscriber instance.
 *
 * Therefore we have only one set of these callback functions, rather
 * than separate sets for each group to which we may join or subscribe.
 */

/*
 * Delayed errors are errors asynchronously detected by Group Services.
 * These may be in response to any protocol proposal we submit, and
 * specify that there is something amiss with the proposal.
 *
 * However, a common delayed error will probably be HA_GS_COLLIDE
 * errors, when we submit a transient protocol proposal at the same
 * time another provider in our group does also, and Group Services
 * chooses a proposal other than ours to execute.
 */
void delayed_error_cb(const ha_gs_delayed_error_notification_t *note){
    write_the_time();
    printf("Delayed Error Callback called\n");
    
    write_the_delayed_error(note);

    fflush(stdout); return;
}

/*
 * A responsiveness callback has arrived, Group Services is asking if
 * the process is still able to respond to callbacks.  If we are running
 * on autopilot (interactiveResponse == FALSE) then simply say "we are
 * OK (HA_GS_CALLBACK_OK).  If we are not on autopilot, then query the
 * user for the response.
 */
ha_gs_callback_rc_t responsive_cb(const ha_gs_responsiveness_notification_t *note) {

    ha_gs_callback_rc_t  _rc;
    const ha_gs_responsiveness_t *_response;
    ha_gs_time_limit_t      _time;

    handledResponsiveness = 1;

    _response = &(note->gs_responsiveness_information);
    _time = _response->gs_responsiveness_response_time_limit;

    /* Auto response, not verbose mode.  Succint signal. */

    if ((!interactiveResponse) && (!verbose)) {
        printf("Rcb");
        fflush(stdout);
        return HA_GS_CALLBACK_OK;
    }

    /* Full output, maybe manual input. */

    write_the_time();
    printf("Responsiveness Callback called\n");

    write_the_notification(0, (void *)note, HA_GS_RESPONSIVENESS_NOTIFICATION);

    /* Auto answer? */

    if (!interactiveResponse) {
        printf("Automatic responsiveness response being made.  I'm fine.\n");
        fflush(stdout);
        return HA_GS_CALLBACK_OK;
    }

    /* Manual answer.   */

    _rc = get_response(_time);

    if (HA_GS_CALLBACK_OK == _rc) {
        printf("Very good, boss.  We are still alive.\n");
    } else {
        printf("Sneaky, sneaky.  Playing dead, are we?\n");
    }

    return(_rc);
}

/*
 * Required, but will not currently be executed.
 */
void query_cb(const ha_gs_query_notification_t *note){
    write_the_time();
    printf("Query callback called\n");
    fflush(stdout);
    return;
}

void domain_control_cb(const ha_gs_domain_control_notification_t *note){
    ha_gs_rc_t rc;
    int _input;
    char _newline;

    write_the_time();
    printf("Domain control callback called\n");
    fflush(stdout);

    printf(" notification_type(%s)\n",
             write_the_notification_type( note->notification_type ));
    fflush(stdout);
    printf("  domain_event_type(%s)\n",
              write_the_domain_event_type( note->domain_event_type ));
    fflush(stdout);

	if (HA_GS_DOMAIN_MERGE == note->domain_event_type)
	{
		unsigned int i;

		printf("  MERGE!!!\n");
    	fflush(stdout);
		printf("  this domain\n");
    	fflush(stdout);
		printf("    ns node number(%u)\n", note->info.merge.gs_domain.node_number);
    	fflush(stdout);
		printf("    ns instance number(%u)\n", note->info.merge.gs_domain.instance_id);
    	fflush(stdout);
		printf("    ns size(%u)\n", note->info.merge.gs_domain.size);
    	fflush(stdout);
		printf("    nodes:\n");
    	fflush(stdout);

		for (i=0; i<note->info.merge.gs_domain_members->gs_count; i++)
		{
			printf("      %i\n", note->info.merge.gs_domain_members->gs_nodes[i].node_number);
		   	fflush(stdout);
		}

		printf("  other domain\n");
    	fflush(stdout);
		printf("    ns node number(%u)\n", note->info.merge.other_domain.node_number);
    	fflush(stdout);
		printf("    ns instance number(%u)\n", note->info.merge.other_domain.instance_id);
    	fflush(stdout);
		printf("    ns size(%u)\n", note->info.merge.other_domain.size);
    	fflush(stdout);
		printf("    nodes:\n");
    	fflush(stdout);

		for (i=0; i<note->info.merge.other_domain_members->gs_count; i++)
		{
			printf("      %i\n", note->info.merge.other_domain_members->gs_nodes[i].node_number);
		   	fflush(stdout);
		}
        }
        else if (HA_GS_SITE_SPLIT == note->domain_event_type)
        {
                printf("    local site number (%d)\n", note->info.site_split.gs_local_site.site_number);
                printf("    other site number (%d)\n", note->info.site_split.gs_other_site.site_number);
                fflush(stdout);
        }
        else if (HA_GS_SITE_MERGE == note->domain_event_type)
        {
                printf("    local site number (%d), up-node-count (%d)\n", note->info.site_merge.gs_local_site.site_number, 
								note->info.site_merge.gs_local_site.site_size);
                printf("    other site number (%d), up-node-count (%d)\n", note->info.site_merge.gs_other_site.site_number,
								note->info.site_merge.gs_other_site.site_size);
                fflush(stdout);

	}
	else if(HA_GS_DOMAIN_MASTER_NODE == note->domain_event_type)
	{
		ha_gs_domain_spec_t domain = note->info.domain_master_info;
		printf("    Domain master (NS) node number: %d\n", domain.node_number);
	}
	else if( HA_GS_MIGRATE_TO_CAA == note->domain_event_type ){
		printf("  Migration sub-type(%s), reason(%s), reason_detail_code(%d), reason_msg(%s)\n", 
                          write_the_migration_event_sub_type( note->info.migrate_event_info.sub_type ),        
                          write_the_migration_event_reason( note->info.migrate_event_info.reason ),        
                          note->info.migrate_event_info.reason_detail_code,      
                          note->info.migrate_event_info.reason_msg );        

		if( HA_GS_DOMAIN_CAA_MIGRATION_COORD == note->info.migrate_event_info.sub_type ){
			/*TBD*/
		} else if( HA_GS_DOMAIN_CAA_MIGRATION_APPRVD == note->info.migrate_event_info.sub_type ){
                        printf("Call ha_gs_migrate_to_caa_commit() or abort the migration?\n" );
                        printf("Enter: 0 (commit) 1 (abort)\n" );
                        fflush(stdout);
                        scanf("%d%c", &_input, &_newline );
                        switch(_input) {
                        case 0:
			    /* call ha_gs_migrate_to_caa_commit() */
                            printf( "Call ha_gs_migrate_to_caa_commit()\n" );
			    rc = ha_gs_migrate_to_caa_commit();
                            printf("ha_gs_migrate_to_caa_commit() returned (%s)\n",
                                    write_an_rc(rc));
                            break;
                        case 1:
                            printf( "Call ha_gs_migrate_to_caa_abort()\n" );
                            rc = ha_gs_migrate_to_caa_abort();
                            printf("ha_gs_migrate_to_caa_abort() returned (%s)\n",
                                    write_an_rc(rc));
                            break;
                        default:
			    /* Default call ha_gs_migrate_to_caa_commit() */
                            printf( "Call ha_gs_migrate_to_caa_commit()\n" );
			    rc = ha_gs_migrate_to_caa_commit();
                            printf("ha_gs_migrate_to_caa_commit() returned (%s)\n",
                                    write_an_rc(rc));
                            break; 
                        }
		} else if( HA_GS_DOMAIN_CAA_MIGRATION_REJCTD == note->info.migrate_event_info.sub_type ){
                        if( note->info.migrate_event_info.reason == HA_GS_HB_MIGRATE_TO_CAA_PREP_FAILED ||
                            note->info.migrate_event_info.reason == HA_GS_CT2PRMMIGRATETOCAAPREP_FAILED )
                        {
                            printf( "Call ha_gs_migrate_to_caa_abort()\n" );
                            rc = ha_gs_migrate_to_caa_abort();
                            printf("ha_gs_migrate_to_caa_abort() returned (%s)\n",
                                write_an_rc(rc));
                        } else {
                            printf("Too late to call ha_gs_migrate_to_caa_abort()\n");
                        }
		} else if( HA_GS_DOMAIN_CAA_MIGRATION_COMPLT == note->info.migrate_event_info.sub_type ){
			/* noop for this test */             
		}
	}
        else if( HA_GS_OPQUORUM_INFO == note->domain_event_type ){
                printf("    Notification Sequence: (%llu)\n", note->info.quorum_val.notification_sequence);
                printf("    Old Quorum Value: (%d)\n", note->info.quorum_val.old_quorum_val);
                printf("    New Quorum Value: (%d)\n", note->info.quorum_val.new_quorum_val);
                printf("    Event Seq Number: (%llu)\n", note->info.quorum_val.gs_event_seqnum);

                recvd_quorum_info_seqnum = note->info.quorum_val.notification_sequence;

                if ((is_split_recvd) && (note->info.quorum_val.gs_event_seqnum >= recvd_split_seqnum)){
                     printf("Received quorum notification is related to split and will be processed.\n");
                }

                if ((is_split_recvd) && ((last_recvd_quorum_value == HA_GS_QUORUM_STATE_PENDING) && ((note->info.quorum_val.new_quorum_val == HA_GS_QUORUM_STATE_HAS) || 
                                                                                                     (note->info.quorum_val.new_quorum_val == HA_GS_QUORUM_STATE_NONE)))){
                     printf("Processing of quorum notifications related to split is complete.\n");
                     is_split_recvd = 0;
                } else {
                     last_recvd_quorum_value = note->info.quorum_val.new_quorum_val;
                }

                if ((is_merge_recvd) && (note->info.quorum_val.gs_event_seqnum >= recvd_merge_seqnum)){
                     printf("Received quorum notification is related to merge and will be processed.\n");
                }

                if ((is_merge_recvd) && ((last_recvd_quorum_value == HA_GS_QUORUM_STATE_PENDING) && ((note->info.quorum_val.new_quorum_val == HA_GS_QUORUM_STATE_HAS) ||
                                                                                                     (note->info.quorum_val.new_quorum_val == HA_GS_QUORUM_STATE_NONE)))){
                     printf("Processing of quorum notifications related to merge is complete.\n");
                     is_merge_recvd = 0;
                } else {
                     last_recvd_quorum_value = note->info.quorum_val.new_quorum_val;
                }

                fflush(stdout);
        }
        else if (HA_GS_SUBCLUSTER_SPLIT == note->domain_event_type)
        {
                int count = 0;

                is_split_recvd = 1;

                printf("    split subtype(%u)\n", note->info.subcluster_split.gs_subcluster_type);
                printf("    local up node count(%u), ", note->info.subcluster_split.gs_local_subcluster.gs_count);
                printf("    split event seqnum(%llu), ", note->info.subcluster_split.gs_event_seqnum);

                recvd_split_seqnum = note->info.subcluster_split.gs_event_seqnum;

                printf("local up node shids(");
                for (count = 0; count < note->info.subcluster_split.gs_local_subcluster.gs_count; count++)
                {
                    if (count == 0)
                    {
                        printf("%u", note->info.subcluster_split.gs_local_subcluster.gs_nodes[count].node_number);
                    }
                    else
                    {
                        printf(",%u", note->info.subcluster_split.gs_local_subcluster.gs_nodes[count].node_number);
                    }
                }

                printf (")\n");

                printf("    remote up node count(%u), ", note->info.subcluster_split.gs_other_subcluster.gs_count);

                printf("remote up node shids(");
                for (count = 0; count < note->info.subcluster_split.gs_other_subcluster.gs_count; count++)
                {
                    if (count == 0)
                    {
                        printf("%u", note->info.subcluster_split.gs_other_subcluster.gs_nodes[count].node_number);
                    }
                    else
                    {
                        printf(",%u", note->info.subcluster_split.gs_other_subcluster.gs_nodes[count].node_number);
                    }
                }

                printf (")\n");

                if (note->info.subcluster_split.gs_subcluster_type == HA_GS_SUBCLUSTER_TYPE_REMOTE)
                {
				    /* BEAM FIX: struct as vararg */
                    printf ("    local site subcluster details - site_number(%u), site_policy(%u), site_priority(%u), site_uuid(0x%llx-%llx)\n",
                                              note->info.subcluster_split.gs_local_site.site_number,
                                              note->info.subcluster_split.gs_local_site.site_policy,
                                              note->info.subcluster_split.gs_local_site.site_priority,
                                              note->info.subcluster_split.gs_local_site.site_uuid.val.bits64[0], 
                                              note->info.subcluster_split.gs_local_site.site_uuid.val.bits64[1]);

                    /* BEAM FIX: struct as vararg */
                    printf ("    other site subcluster details - site_number(%u), site_policy(%u), site_priority(%u), site_uuid(0x%llx-%llx)\n",
                                              note->info.subcluster_split.gs_other_site.site_number,
                                              note->info.subcluster_split.gs_other_site.site_policy,
                                              note->info.subcluster_split.gs_other_site.site_priority,
                                              note->info.subcluster_split.gs_other_site.site_uuid.val.bits64[0],
                                              note->info.subcluster_split.gs_other_site.site_uuid.val.bits64[1]);
                }
                else if (note->info.subcluster_split.gs_subcluster_type == HA_GS_SUBCLUSTER_TYPE_LOCAL)
                {
                    printf ("    local domain details - node_number(%u), instance_id(%u), size(%u)\n",
                                            note->info.subcluster_split.gs_local_domain.node_number,
                                            note->info.subcluster_split.gs_local_domain.instance_id,
                                            note->info.subcluster_split.gs_local_domain.size);
                }

                fflush(stdout);
        }
        else if (HA_GS_SUBCLUSTER_MERGE == note->domain_event_type)
        {
                int count = 0;

                is_merge_recvd = 1;

                printf("    merge subtype(%u)\n", note->info.subcluster_merge.gs_subcluster_type);
                printf("    local up node count(%u), ", note->info.subcluster_merge.gs_local_subcluster.gs_count);
                printf("    merge event seqnum(%llu), ", note->info.subcluster_merge.gs_event_seqnum);

                recvd_merge_seqnum = note->info.subcluster_merge.gs_event_seqnum;

                printf("local up node shids(");
                for (count = 0; count < note->info.subcluster_merge.gs_local_subcluster.gs_count; count++)
                {
                    if (count == 0)
                    {
                        printf("%u", note->info.subcluster_merge.gs_local_subcluster.gs_nodes[count].node_number);
                    }
                    else
                    {
                        printf(",%u", note->info.subcluster_merge.gs_local_subcluster.gs_nodes[count].node_number);
                    }
                }

                printf (")\n");

                printf("    remote up node count(%u), ", note->info.subcluster_merge.gs_other_subcluster.gs_count);

                printf("remote up node shids(");
                for (count = 0; count < note->info.subcluster_merge.gs_other_subcluster.gs_count; count++)
                {
                    if (count == 0)
                    {
                        printf("%u", note->info.subcluster_merge.gs_other_subcluster.gs_nodes[count].node_number);
                    }
                    else
                    {
                        printf(",%u", note->info.subcluster_merge.gs_other_subcluster.gs_nodes[count].node_number);
                    }
                }

                printf (")\n");

                if (note->info.subcluster_merge.gs_subcluster_type == HA_GS_SUBCLUSTER_TYPE_REMOTE)
                {
                    /* BEAM FIX: struct as vararg */
                    printf ("    local site subcluster details - site_size(%u), site_number(%u), site_policy(%u), site_priority(%u), site_uuid(0x%llx-%llx)\n",
                                              note->info.subcluster_merge.gs_local_site.site_size,
                                              note->info.subcluster_merge.gs_local_site.site_number,
                                              note->info.subcluster_merge.gs_local_site.site_policy,
                                              note->info.subcluster_merge.gs_local_site.site_priority,
                                              note->info.subcluster_merge.gs_local_site.site_uuid.val.bits64[0],
                                              note->info.subcluster_merge.gs_local_site.site_uuid.val.bits64[1]);

                    /* BEAM FIX: struct as vararg */
                    printf ("    other site subcluster details - site_size(%u), site_number(%u), site_policy(%u), site_priority(%u), site_uuid(0x%llx-%llx)\n",
                                              note->info.subcluster_merge.gs_other_site.site_size,
                                              note->info.subcluster_merge.gs_other_site.site_number,
                                              note->info.subcluster_merge.gs_other_site.site_policy,
                                              note->info.subcluster_merge.gs_other_site.site_priority,
                                              note->info.subcluster_merge.gs_other_site.site_uuid.val.bits64[0],
                                              note->info.subcluster_merge.gs_other_site.site_uuid.val.bits64[1]);
                }
                else if (note->info.subcluster_merge.gs_subcluster_type == HA_GS_SUBCLUSTER_TYPE_LOCAL)
                {
                    printf ("    local domain details - node_number(%u), instance_id(%u), size(%u)\n",
                                            note->info.subcluster_merge.gs_local_domain.node_number,
                                            note->info.subcluster_merge.gs_local_domain.instance_id,
                                            note->info.subcluster_merge.gs_local_domain.size);
                }

                fflush(stdout);
        }
        else if( HA_GS_DOMAIN_NODE_CONFIG ==  note->domain_event_type)
        {
                write_domain_membership_info( &note->info.nodes );
                fflush(stdout);
        }
        else if( HA_GS_DOMAINCB_RESP_ERR_INFO == note->domain_event_type )
        {
                if ( note->info.domaincb_resp_err.domain_event_type == HA_GS_OPQUORUM_INFO ){
                     printf("    Quorum Response Error Code: (%d)\n", note->info.domaincb_resp_err.err_info.quorum_resp_err.error_code);
                }
                fflush(stdout);
        }
        else if( HA_GS_DOMAIN_STATUS_CHANGE == note->domain_event_type )
       {
                     printf("    Domain Status Change notification received\n");
                     printf("    Notification Sequence: %llu\n", note->info.domain_status_info.notification_sequence);
                     if ( note->info.domain_status_info.domain_status == HA_GS_DOMAIN_STATUS_ACTIVE_OR_RESUMED ){ 
                           printf("      Current Domain Status:  ACTIVE (%d).\n", note->info.domain_status_info.domain_status);
                     }
                     if ( note->info.domain_status_info.domain_status == HA_GS_DOMAIN_STATUS_SUSPENDED ){
                          printf("      Current Domain Status:  SUSPENDED (%d).\n",  note->info.domain_status_info.domain_status);
                     }

                     fflush(stdout); 
        }


    return;
}

/**********************************************************************/
/*
 * Following are the sets of callback functions, separated so that each
 * pre-defined group has its own set of functions.  The scheme is as
 * follows:
 *      theSourceGroup - 0 (zero, e.g., n_phase_cb0()).
 *      OnePhaseJoin -  1 (one, e.g., n_phase_cb1()).
 *      theTargetGroup - 2 (two, e.g., n_phase_cb2()).
 *      theLonelyGroup - 3 (three, e.g., n_phase_cb3()).
 *      ifFirstIWin - 4 (four, e.g., n_phase_cb4()).
 *      SourceOrNot - 5 (five, e.g., n_phase_cb5()).
 *      ChainGang - 6 (six, e.g., n_phase_cb6()).
 *
 *    The user-defined group(s) all share the callback functions with
 *      integer suffix 7 (seven, e.g., n_phase_cb7()).
 *
 * Note that there is no Group Services requirement that we do it this
 * way.  Instead, we could use the "gs_provider_token" field that is
 * passed in the notification as an index to our own data structures,
 * and this would tell us the group to which a notification should
 * apply.
 *
 * Also, if your process never plans to join more than one group, there
 * is no need for multiple sets of callback functions.
 *
 * We do it this way as an extreme example.  In addition, if you would
 * like to customize the actions taken by any one or more sets of
 * callback functions, this makes it quite easy to do so.
 */

/*
 * The callback structure is identical for each set.  Each set has the
 * following:
 *  n_phase callback
 *  approved callback
 *  rejected callback
 *  announcement callback
 *  merge callback
 *  subscription callback (if you subscribed to the pre-defined group).
 *
 * Each callback function does some amount of verification, to ensure
 * that the data in the notification is reasonable, then displays the
 * received notification.
 *
 * In the case of the n_phase callback, it then queries the user to get
 * a vote value, and will then submit the vote, optionally along with a
 * state value change, and/or provider-broadcast message, and/or a
 * default vote change.
 */
/*********************************************************************/

void n_phase_cb0(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"};
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned			i, mask, which_msg;
    int                         _msglen;
    char _newline;
    int ck_checksum = 0;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback Zero called\n");

    write_the_notification(0, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (noteToken != gid[0])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[0]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type));
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask));
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|");
    }
    printf("\n");

    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);
    
    /* for message length >= 2000 send the same  message with the vote */
    if( (note->gs_proposal->gs_provider_message != 0) &&
        (note->gs_proposal->gs_provider_message->gs_length >= 2000) )
    {
        _sValue = 0;
        _msglen = note->gs_proposal->gs_provider_message->gs_length;
        _pValue = (ha_gs_provider_message_t *)malloc(sizeof(ha_gs_provider_message_t));
        _pValue->gs_length= _msglen;
        _pValue->gs_message = (char *)malloc( _msglen * sizeof(char) );
        memcpy( _pValue->gs_message, note->gs_proposal->gs_provider_message->gs_message, _msglen);

    } else {
        /* this means it is at "p" option and so use original code */ 
        create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);
    }
    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
	fflush(stdout); 
    }
    fflush(stdout); 
    if( _sValue != 0 && _pValue != 0){
        free_state_and_pbm(_sValue, _pValue);
    } 
    if( _sValue != 0){
        free(_sValue);
    }
    if(_pValue != 0){
        free(_pValue);
    }
    fflush(stdout); return;
}
void approved_cb0(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback Zero called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(0, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[0]) {
            in_group[0] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[0])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[0]);
    }
    fflush(stdout); return;
}
void rejected_cb0(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback Zero called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(0, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[0])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[0]);
    }
    fflush(stdout); return;
}
void announce_cb0(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback Zero called\n");
    write_the_notification(0, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb0(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback Zero called\n");
    fflush(stdout); return;
}

void subscribe_cb0(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback Zero for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback Zero called, with unknown token [%d]\n",
	       noteToken);
    }

    fflush(stdout); return;
}

/**********************************************************************/

void n_phase_cb1(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"};
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned int        i, mask, whatchanged, which_msg;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback One called\n");

    write_the_notification(1, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (noteToken != gid[1])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[1]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type));
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask));
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|");
    }
    printf("\n");
	
    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);

    create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);

    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
    }

    free(_sValue);
    free(_pValue);

    fflush(stdout); return;
}
void approved_cb1(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback One called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(1, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[1]) {
            in_group[1] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[1])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[1]);
    }
    fflush(stdout); return;
}
void rejected_cb1(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback One called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(1, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[1])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[1]);
    }
    fflush(stdout); return;
}
void announce_cb1(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback One called\n");
    write_the_notification(1, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb1(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback One called\n");
    fflush(stdout); return;
}

void subscribe_cb1(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback One for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback One called, with unknown token [%d]\n",
	       noteToken);
    }

    fflush(stdout); return;
}

/**********************************************************************/

void n_phase_cb2(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"}; 
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned			i, mask, which_msg;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback Two called\n");

    write_the_notification(2, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }

    if (noteToken != gid[2])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[0]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type)); 
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask)); 
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|"); 
    }
    printf("\n");

    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d, REJECT!.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);

    create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);

    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
    }

    free(_sValue);
    free(_pValue);

    fflush(stdout);
    return;
}
void approved_cb2(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback Two called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(2, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[2]) {
            in_group[2] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[2])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[2]);
    }
    fflush(stdout); return;
}
void rejected_cb2(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback Two called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(2, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[2])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[2]);
    }
    fflush(stdout); return;
}
void announce_cb2(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback Two called\n");
    write_the_notification(2, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb2(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback Two called\n");
    fflush(stdout); return;
}

void subscribe_cb2(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback Two for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback Two called, with unknown token [%d]\n",
	       noteToken);
    }

    fflush(stdout); return;
}

/**********************************************************************/

void n_phase_cb3(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"}; 
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned			i, mask, which_msg;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback Three called\n");

    write_the_notification(3, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }

    if (noteToken != gid[3])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[0]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type)); 
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask)); 
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|"); 
    }
    printf("\n");

    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d, REJECT!.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);

    create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);

    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
    }

    free(_sValue);
    free(_pValue);

    fflush(stdout);
    return;
}
void approved_cb3(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback Three called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(3, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[3]) {
            in_group[3] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[3])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[3]);
    }
    fflush(stdout); return;
}
void rejected_cb3(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback Three called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(3, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[3])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[3]);
    }
    fflush(stdout); return;
}
void announce_cb3(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback Three called\n");
    write_the_notification(3, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb3(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback Three called\n");
    fflush(stdout); return;
}

void subscribe_cb3(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback Three for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback Three called, with unknown token [%d]\n",
	       noteToken);
    }

    fflush(stdout); return;
}

/**********************************************************************/

void n_phase_cb4(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"}; 
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned			i, mask, which_msg;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback Four called\n");

    write_the_notification(4, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }

    if (noteToken != gid[4])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[0]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type)); 
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask)); 
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|"); 
    }
    printf("\n");

    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d, REJECT!.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);

    create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);

    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
    }

    free(_sValue);
    free(_pValue);

    fflush(stdout);
    return;
}
void approved_cb4(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback Four called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(4, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[4]) {
            in_group[4] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[4])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[4]);
    }
    fflush(stdout); return;
}
void rejected_cb4(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback Four called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(4, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[4])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[4]);
    }
    fflush(stdout); return;
}
void announce_cb4(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback Four called\n");
    write_the_notification(4, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb4(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback Four called\n");
    fflush(stdout); return;
}

void subscribe_cb4(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback Four for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback Four called, with unknown token [%d]\n",
	       noteToken);
    }
    fflush(stdout); return;
}

/**********************************************************************/

void n_phase_cb5(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"};
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned			i, mask, which_msg;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback Five called\n");

    write_the_notification(5, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (noteToken != gid[5])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[5]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type));
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask));
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|");
    }
    printf("\n");

    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);

    create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);

    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
    }

    free(_sValue);
    free(_pValue);

    fflush(stdout); return;
}
void approved_cb5(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback Five called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(5, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[5]) {
            in_group[5] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[5])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[5]);
    }
    fflush(stdout); return;
}
void rejected_cb5(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback Five called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(5, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[5])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[5]);
    }
    fflush(stdout); return;
}
void announce_cb5(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback Five called\n");
    write_the_notification(5, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb5(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback Five called\n");
    fflush(stdout); return;
}

void subscribe_cb5(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback Five for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback Five called, with unknown token [%d]\n",
	       noteToken);
    }
    fflush(stdout); return;
}

/**********************************************************************/

void n_phase_cb6(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"};
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned			i, mask, which_msg;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback Six called\n");

    write_the_notification(6, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (noteToken != gid[6])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[6]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type));
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask));
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|");
    }
    printf("\n");

    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);

    create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);

    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
    }

    free(_sValue);
    free(_pValue);

    fflush(stdout); return;
}
void approved_cb6(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback Six called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(6, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[6]) {
            in_group[6] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[6])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[6]);
    }
    fflush(stdout); return;
}
void rejected_cb6(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback Six called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(6, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[6])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[6]);
    }
    fflush(stdout); return;
}
void announce_cb6(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback Six called\n");
    write_the_notification(6, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb6(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback Six called\n");
    fflush(stdout); return;
}

void subscribe_cb6(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback Six for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback Six called, with unknown token [%d]\n",
	       noteToken);
    }
    fflush(stdout); return;
}

/**********************************************************************/

void n_phase_cb7(const ha_gs_n_phase_notification_t *note){
    ha_gs_rc_t  rCode;
    ha_gs_state_value_t      *_sValue;
    ha_gs_provider_message_t *_pValue;

    ha_gs_provider_message_t	provider_message = { 13, "Hello World\n"};
    ha_gs_vote_value_t		vote_value, def_vote;
    unsigned			i, mask, which_msg;

    ha_gs_token_t   noteToken = note->gs_provider_token;

    write_the_time();
    printf("N Phase Callback Seven called\n");

    write_the_notification(7, (void *)note, HA_GS_N_PHASE_NOTIFICATION);

    if (note->gs_notification_type != HA_GS_N_PHASE_NOTIFICATION)
    {
	printf("But this wasn't a N-Phase Notification!\n");
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *)0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (noteToken != gid[7])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[7]);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    if (note->gs_protocol_type > MAX_REQUEST)
    {
	printf("protocol_type %d is not valid request type\n",
	       note->gs_protocol_type);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    } else
	printf("Protocol is %s\n",proto_type(note->gs_protocol_type));
    printf("SUMMARY_CODE=");
    mask = HA_GS_MIN_SUMMARY_CODE;
    for(i=1; mask <= HA_GS_MAX_SUMMARY_CODE; i++,mask <<= 1) {
	if (note->gs_summary_code & mask)
	    printf("%s",sum_code(mask));
	else continue;
	if (mask != HA_GS_MAX_SUMMARY_CODE)
	    printf("|");
    }
    printf("\n");

    if (note->gs_proposal->gs_phase_info.gs_phase_number != voting_phase) {
        printf("Phase number not properly incremented, was %d, is now %d.\n",
               voting_phase,
               note->gs_proposal->gs_phase_info.gs_phase_number);
	vote_value = HA_GS_VOTE_REJECT;
	if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                            vote_value,
                                            (void *) 0,
                                            &provider_message,
                                            HA_GS_NULL_VOTE))) {
            printf("Strange error code from ha_gs_vote [%s]\n",
                   write_an_rc(rCode));
            printf("\n");
        }
	fflush(stdout); return;
    }
    which_msg = (voting_phase % NUMBER_MSG_ENTRIES);
    voting_phase++;
	
    vote_value = get_a_vote(note->gs_proposal->gs_phase_info.gs_phase_number);
    def_vote = default_vote_array[which_msg];
    printf("Phase[%d]", note->gs_proposal->gs_phase_info.gs_phase_number);
    write_the_vote(vote_value);
    printf("default ");
    write_the_vote(def_vote);
    printf("\n");
    printf(starz);

    create_state_and_pbm(which_msg, &_sValue, &_pValue, 0, 0);

    if (HA_GS_OK != (rCode = ha_gs_vote(noteToken,
                                        vote_value,
                                        _sValue,
                                        _pValue,
                                        def_vote))) {
        printf("Strange error code from ha_gs_vote [%s]\n",
               write_an_rc(rCode));
        printf("\n");
    }

    free(_sValue);
    free(_pValue);

    fflush(stdout); return;
}
void approved_cb7(const ha_gs_approved_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback Seven called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(7, (void *)note, HA_GS_APPROVED_NOTIFICATION);

    if (HA_GS_JOIN == note->gs_protocol_type) {
        if (0 == in_group[7]) {
            in_group[7] = 1;
            in_group_count++;
        }
    }

    if (noteToken != gid[7])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[7]);
    }
    fflush(stdout); return;
}
void rejected_cb7(const ha_gs_rejected_notification_t *note){

    ha_gs_token_t   noteToken;

    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Rejected Callback Seven called\n");

    voting_phase = 1;                   /* reset for next protocol. */

    write_the_notification(7, (void *)note, HA_GS_REJECTED_NOTIFICATION);

    if (noteToken != gid[7])
    {
	printf("Provider token = %d my provider token is %d\n",
	       note->gs_provider_token, gid[7]);
    }
    fflush(stdout); return;
}
void announce_cb7(const ha_gs_announcement_notification_t *note){
    write_the_time();
    printf("Announce Callback Seven called\n");
    write_the_notification(7, (void *)note, HA_GS_ANNOUNCEMENT_NOTIFICATION);
    fflush(stdout); return;
}
void merge_cb7(const ha_gs_merge_notification_t *note){
    write_the_time();
    printf("Merge Callback Seven called\n");
    fflush(stdout); return;
}

void subscribe_cb7(const ha_gs_subscription_notification_t *note){

    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback Seven for group [%s] called\n",
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback Seven called, with unknown token [%d]\n",
	       noteToken);
    }
    fflush(stdout); return;
}
void approved_cb26(const ha_gs_approved_notification_t *note)
{
    ha_gs_rc_t rc;
    ha_gs_token_t   noteToken;
    ha_gs_proposal_info_t proposal;
    int len;
    char * pbm = NULL;  /* BEAM FIX: uninitialized */
    static int count = 0;


    noteToken = note->gs_provider_token;

    write_the_time();
    printf("Approved Callback 26 called\n");

    if( note->gs_protocol_type == HA_GS_JOIN ){
        if( count < 1 ){
            pbm = (char *)malloc( (MSGLEN+1) * sizeof(char) );   /* BEAM FIX: accessing beyond memory */
            memset( pbm, '0', MSGLEN+1 );
            pbm[MSGLEN]='\0';
            len = strlen(pbm);
            proposal.gs_message_request.gs_num_phases = HA_GS_1_PHASE;
            proposal.gs_message_request.gs_time_limit = 0;
            proposal.gs_message_request.gs_message.gs_length = len;
            proposal.gs_message_request.gs_message.gs_message = (char *)pbm;

            printf("Join approved, send 1MB message.\n");
            rc=ha_gs_send_message(noteToken, &proposal);
        } else {
            printf("Join approved.\n");
        }
        count++;
    }else if( note->gs_protocol_type & HA_GS_PROVIDER_MESSAGE ){
        if( note->gs_proposal->gs_provider_message->gs_length != 0 ){
            printf("Got the big message, msgLength=%d\n",
            note->gs_proposal->gs_provider_message->gs_length);
            rc = ha_gs_goodbye( note->gs_provider_token );
            printf("ha_gs_goodbye() called.");
            count = 0;
        } else {
            printf("No message.\n");
        }
    }
    if( pbm != NULL ){
        free(pbm);
    }
    fflush(stdout); 
    return;
}

/*********************************************************************/
/*
 * These callback functions are used for subscriptions to System
 * Membership groups and arbitrary groups.
 */

/*
 * Handle notifications if subscribed to the 'Host Membership' group.
 */
void subscribe_cb_HostMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("Host Membership", note);
    return;
}

/*
 * Handle notifications if subscribed to the 'Ethernet Adapter Membership'
 * group.
 */
void subscribe_cb_EnetMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("Ethernet Membership", note);
    return;
}

/*
 * Handle notifications if subscribed to the 'High Performance Switch
 * Adapter Membership' group.
 */
void subscribe_cb_CssMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("CSS Membership", note);
    return;
}

/*
 * Handle notifications if subscribed to the 'Token Ring Adapter
 * Membership' group.
 */
void subscribe_cb_TrMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("Token Ring Membership", note);
    return;
}

/*
 * Handle notifications if subscribed to the 'FDDI Adapter Membership'
 * group.
 */
void subscribe_cb_FddiMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("FDDI Membership", note);
    return;
}

/*
 * Handle notifications if subscribed to the 'RS 232 Adapter Membership'
 * group.
 */
void subscribe_cb_RS232Mbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("RS232 Membership", note);
    return;
}

/*
 * Handle notifications if subscribed to the 'Target-Mode SCSI Adapter
 * Membership' group.
 */
void subscribe_cb_TmScsiMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("Target-Mode SCSI Membership", note);
    return;
}

/*
 * Handle notifications if subscribed to the 'SLIP Adapter Membership'
 * group.
 */
void subscribe_cb_SlipMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("SLIP Membership", note);
    return;
}
/*
 * Handle notifications if subscribed to the 'Myrinet  Membership'
 * group.
 */
void subscribe_cb_MyrinetMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("Myrinet Membership", note);
    return;
}
/*
 * Handle notifications if subscribed to the 'CSS1 Membership'
 * group.
 */
void subscribe_cb_Css1Mbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("CSS1 Membership", note);
    return;
}

void subscribe_cb_CssRawMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("CSSRAW Membership", note);
    return;
}
void subscribe_cb_fcMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("fc Membership", note);
    return;
}
void subscribe_cb_bondMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("bond Membership", note);
    return;
}
void subscribe_cb_eipMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("eip Membership", note);
    return;
}
void subscribe_cb_AllAdaptMbr(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("AllAdapter Membership", note);
    return;
}

/*
 * Do the "common" processing for all of the adapter membership subscriptions.
 */
void subscribe_common_AM(char *callback_name,
                         const ha_gs_subscription_notification_t *note)
{
    ha_gs_token_t   noteToken;
    int             idx;

    noteToken = note->gs_subscriber_token;

    if (-1 != (idx = get_sub_index(noteToken))) {

        write_the_time();
        printf("Subscription Callback %s for group [%s] called\n",
               callback_name,
               subNames[idx]);

        write_the_subscription(note);

        fflush(stdout);
    } else {
        
        write_the_time();
	printf("Subscription Callback %s called, with unknown token [%d]\n",
               callback_name,
	       noteToken);
    }
    return;
}

/*
 * Handle notifications if subscribed to arbitrary groups.  The 's'
 * command of sample_test allows the user to specify any existing group
 * name for subscription.  All such subscriptions use this callback
 * function.
 */
void subscribe_cb_Pick(const ha_gs_subscription_notification_t *note)
{
    subscribe_common_AM("Pick", note);
    return;
}
