Update of /cvsroot/ltp/ltp/testcases/open_hpi_testsuite/openhpid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14452/ltp/testcases/open_hpi_testsuite/openhpid Added Files: oh_client.cpp oh_client.h oh_client_conf.c oh_client_conf.h oh_client_session.cpp oh_client_session.h Log Message: Update to OpenHPI 2.12.0 (see www.openhpi.org for more info) --- NEW FILE: oh_client_conf.h --- /* -*- linux-c -*- * * (C) Copyright IBM Corp. 2008 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * Renier Morales <re...@op...> * */ #include <glib.h> #include <SaHpi.h> struct oh_domain_conf { SaHpiDomainIdT did; char host[SAHPI_MAX_TEXT_BUFFER_LENGTH]; unsigned int port; }; int oh_load_client_config(const char *filename, GHashTable *domains); --- NEW FILE: oh_client.h --- /* -*- linux-c -*- * * (C) Copyright IBM Corp. 2004-2008 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * W. David Ashley <da...@us...> * Renier Morales <re...@op...> * */ #ifndef __OH_CLIENT_H #define __OH_CLIENT_H /*----------------------------------------------------------------------------*/ /* Macros */ /*----------------------------------------------------------------------------*/ #define SendRecv(sid, cmd) \ if (pinst->WriteMsg(request)) { \ client_err(cmd, "WriteMsg failed\n"); \ g_free(request); \ if (sid) oh_close_connx(sid); \ else oh_delete_connx(pinst); \ return SA_ERR_HPI_NO_RESPONSE; \ } \ if (pinst->ReadMsg(reply)) { \ client_err(cmd, "Read failed\n"); \ g_free(request); \ if (sid) oh_close_connx(sid); \ else oh_delete_connx(pinst); \ return SA_ERR_HPI_NO_RESPONSE; \ } #define SendRecvNoReturn(cmd) \ if (pinst->WriteMsg(request)) { \ client_err(cmd, "WriteMsg failed\n"); \ g_free(request); \ oh_delete_connx(pinst); \ return; \ } \ if (pinst->ReadMsg(reply)) { \ client_err(cmd, "Read failed\n"); \ g_free(request); \ oh_delete_connx(pinst); \ return; \ } #endif /* __OH_CLIENT_H */ --- NEW FILE: oh_client_conf.c --- /* -*- linux-c -*- * * (C) Copyright IBM Corp. 2008 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Authors: * Renier Morales <re...@op...> */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <oHpi.h> #include <oh_error.h> #include <oh_domain.h> #include <oh_client_conf.h> #include <config.h> /******************************************************************************* * In order to use the glib lexical parser we need to define token * types which we want to switch on ******************************************************************************/ enum { HPI_CLIENT_CONF_TOKEN_DOMAIN = G_TOKEN_LAST, HPI_CLIENT_CONF_TOKEN_DEFAULT, HPI_CLIENT_CONF_TOKEN_HOST, HPI_CLIENT_CONF_TOKEN_PORT } hpiClientConfType; struct tokens { gchar *name; guint token; }; static struct tokens oh_client_conf_tokens[] = { { .name = "domain", .token = HPI_CLIENT_CONF_TOKEN_DOMAIN }, { .name = "default", .token = HPI_CLIENT_CONF_TOKEN_DEFAULT }, { .name = "host", .token = HPI_CLIENT_CONF_TOKEN_HOST }, { .name = "port", .token = HPI_CLIENT_CONF_TOKEN_PORT } }; /******************************************************************************* * In order to initialize the lexical scanner, you need the following config. * This config was figured out by reading the glib sources, and lots of * trial and error (documentation for this isn't very good). * * G_TOKEN_STRING will be created when anything starts with a-zA-z_/. * due to cset_identifier_first and identifier2string values below. * Therefor, if you want 0 to be scanned as a string, you need to quote * it (e.g. "0") * *******************************************************************************/ static GScannerConfig oh_scanner_conf = { ( " \t\n" ) /* cset_skip_characters */, ( G_CSET_a_2_z "_/." G_CSET_A_2_Z ) /* cset_identifier_first */, ( G_CSET_a_2_z "_-0123456789/." G_CSET_A_2_Z ) /* cset_identifier_nth */, ( "#\n" ) /* cpair_comment_single */, FALSE /* case_sensitive */, TRUE /* skip_comment_multi */, TRUE /* skip_comment_single */, TRUE /* scan_comment_multi */, TRUE /* scan_identifier */, TRUE /* scan_identifier_1char */, TRUE /* scan_identifier_NULL */, TRUE /* scan_symbols */, TRUE /* scan_binary */, TRUE /* scan_octal */, TRUE /* scan_float */, TRUE /* scan_hex */, TRUE /* scan_hex_dollar */, TRUE /* scan_string_sq */, TRUE /* scan_string_dq */, TRUE /* numbers_2_int */, FALSE /* int_2_float */, TRUE /* identifier_2_string */, TRUE /* char_2_token */, TRUE /* symbol_2_token */, FALSE /* scope_0_fallback */, }; static GTokenType get_next_good_token(GScanner *oh_scanner) { GTokenType next_token; next_token = g_scanner_get_next_token(oh_scanner); while (next_token != G_TOKEN_RIGHT_CURLY && next_token != HPI_CLIENT_CONF_TOKEN_HOST && next_token != HPI_CLIENT_CONF_TOKEN_HOST) { if (next_token == G_TOKEN_EOF) break; next_token = g_scanner_get_next_token(oh_scanner); } return next_token; } static int process_domain_token (GScanner *oh_scanner, GHashTable *domains) { struct oh_domain_conf *domain_conf = NULL; GTokenType next_token; if (g_scanner_get_next_token(oh_scanner) != HPI_CLIENT_CONF_TOKEN_DOMAIN) { err("Processing domain: Expected a domain token"); return -1; } /* Get the domain id and store in Hash Table */ next_token = g_scanner_get_next_token(oh_scanner); if (next_token == HPI_CLIENT_CONF_TOKEN_DEFAULT) { // Default domain domain_conf = g_malloc0(sizeof(struct oh_domain_conf)); // domain_conf->did = SAHPI_UNSPECIFIED_DOMAIN_ID; domain_conf->did = OH_DEFAULT_DOMAIN_ID; dbg("Processing domain: Found default domain definition"); } else if (next_token == G_TOKEN_INT) { if (oh_scanner->value.v_int == 0) { // Domain Id of 0 is invalid err("Processing domain: A domain id of 0 is invalid"); return -2; } domain_conf = g_malloc0(sizeof(struct oh_domain_conf)); domain_conf->did = (SaHpiDomainIdT)oh_scanner->value.v_int; dbg("Processing domain: Found domain definition"); } else { err("Processing domain: Expected int or string ('default') token"); return -3; } /* Check for Left Brace token type. If we have it, then continue parsing. */ if (g_scanner_get_next_token(oh_scanner) != G_TOKEN_LEFT_CURLY) { err("Processing domain: Expected left curly token."); goto free_and_exit; } next_token = get_next_good_token(oh_scanner); while (next_token != G_TOKEN_EOF && next_token != G_TOKEN_RIGHT_CURLY) { if (next_token == HPI_CLIENT_CONF_TOKEN_HOST) { next_token = g_scanner_get_next_token(oh_scanner); if (next_token != G_TOKEN_EQUAL_SIGN) { err("Processing domain: Expected equal sign"); goto free_and_exit; } next_token = g_scanner_get_next_token(oh_scanner); if (next_token != G_TOKEN_STRING) { err("Processing domain: Expected a string"); goto free_and_exit; } if (domain_conf->host[0] == '\0') { strncpy(domain_conf->host, oh_scanner->value.v_string, SAHPI_MAX_TEXT_BUFFER_LENGTH); } } else if (next_token == HPI_CLIENT_CONF_TOKEN_PORT) { next_token = g_scanner_get_next_token(oh_scanner); if (next_token != G_TOKEN_EQUAL_SIGN) { err("Processing domain: Expected equal sign"); goto free_and_exit; } next_token = g_scanner_get_next_token(oh_scanner); if (next_token != G_TOKEN_INT) { err("Processing domain: Expected an integer"); goto free_and_exit; } domain_conf->port = oh_scanner->value.v_int; } else { err("Processing domain: Should not get here!"); goto free_and_exit; } next_token = g_scanner_get_next_token(oh_scanner); } if (next_token == G_TOKEN_EOF) { err("Processing domain: Expected a right curly"); goto free_and_exit; } else if (domain_conf->host[0] == '\0') { err("Processing domain: Did not find the host parameter"); goto free_and_exit; } else if (domain_conf->port == 0) { domain_conf->port = OPENHPI_DEFAULT_DAEMON_PORT; } g_hash_table_insert(domains, &domain_conf->did, domain_conf); //printf("domain %d: %s:%d\n", domain_conf->did, domain_conf->host, domain_conf->port); return 0; free_and_exit: /** There was an error reading a token so we need to error out, but not before cleaning up. */ g_free(domain_conf); return -10; } static void scanner_msg_handler (GScanner *scanner, gchar *message, gboolean is_error) { g_return_if_fail (scanner != NULL); err("%s:%d: %s%s\n", scanner->input_name ? scanner->input_name : "<memory>", scanner->line, is_error ? "error: " : "", message ); } int oh_load_client_config(const char *filename, GHashTable *domains) { int oh_client_conf_file, i, done = 0; GScanner *oh_scanner; int num_tokens = sizeof(oh_client_conf_tokens) / sizeof(oh_client_conf_tokens[0]); if (!filename || !domains) { err("Error. Invalid parameters"); return -1; } oh_scanner = g_scanner_new(&oh_scanner_conf); if (!oh_scanner) { err("Couldn't allocate g_scanner for file parsing"); return -2; } oh_scanner->msg_handler = scanner_msg_handler; oh_scanner->input_name = filename; oh_client_conf_file = open(filename, O_RDONLY); if (oh_client_conf_file < 0) { err("Client configuration file '%s' could not be opened", filename); g_scanner_destroy(oh_scanner); return -3; } g_scanner_input_file(oh_scanner, oh_client_conf_file); for (i = 0; i < num_tokens; i++) { g_scanner_scope_add_symbol( oh_scanner, 0, oh_client_conf_tokens[i].name, (void *)((unsigned long)oh_client_conf_tokens[i].token)); } while (!done) { guint my_token; my_token = g_scanner_peek_next_token(oh_scanner); /*dbg("token: %d", my_token);*/ switch (my_token) { case G_TOKEN_EOF: done = 1; break; case HPI_CLIENT_CONF_TOKEN_DOMAIN: process_domain_token(oh_scanner, domains); break; default: /* need to advance it */ my_token = g_scanner_get_next_token(oh_scanner); g_scanner_unexp_token(oh_scanner, G_TOKEN_SYMBOL, NULL, "\"domain\"", NULL, NULL, 1); break; } } if (close(oh_client_conf_file) != 0) { err("Couldn't close file '%s'.", filename); g_scanner_destroy(oh_scanner); return -4; } done = oh_scanner->parse_errors; g_scanner_destroy(oh_scanner); dbg("Done processing conf file.\nNumber of parse errors:%d", done); return 0; } --- NEW FILE: oh_client.cpp --- /* -*- linux-c -*- * * (C) Copyright IBM Corp. 2004-2008 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * W. David Ashley <da...@us...> * Renier Morales <re...@op...> * */ extern "C" { [...5382 lines suppressed...] request = malloc(hm->m_request_len); pinst->header.m_len = HpiMarshalRequest4(hm, request, &id, event, rpte, rdr); SendRecv(0, cmd); int mr = HpiDemarshalReply4(pinst->header.m_flags & dMhEndianBit, hm, reply + sizeof(cMessageHeader), &err, &id, event, rpte, rdr); oh_delete_connx(pinst); if (request) free(request); if (mr < 0) return SA_ERR_HPI_INVALID_PARAMS; return err; } --- NEW FILE: oh_client_session.cpp --- /* -*- linux-c -*- * * (C) Copyright IBM Corp. 2004-2008 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * W. David Ashley <da...@us...> * Renier Morales <re...@op...> * */ #include "oh_client_session.h" extern "C" { #include <pthread.h> #include <oHpi.h> #include <oh_error.h> #include <config.h> #include <oh_domain.h> #include "oh_client_conf.h" } GHashTable *domains = NULL; GHashTable *sessions = NULL; GStaticRecMutex sessions_sem = G_STATIC_REC_MUTEX_INIT; static SaHpiSessionIdT next_client_sid = 1; static void __destroy_client_connx(gpointer data) { struct oh_client_session *client_session = (struct oh_client_session *)data; g_hash_table_destroy(client_session->connxs); g_free(client_session); } int oh_client_init(void) { // Initialize GLIB thread engine if (!g_thread_supported()) { g_thread_init(NULL); } g_static_rec_mutex_lock(&sessions_sem); // Create session table. if (!sessions) { sessions = g_hash_table_new_full( g_int_hash, g_int_equal, NULL, __destroy_client_connx ); } if (!domains) { // Create domain table struct oh_domain_conf *domain_conf = NULL; // SaHpiDomainIdT default_did = SAHPI_UNSPECIFIED_DOMAIN_ID; SaHpiDomainIdT default_did = OH_DEFAULT_DOMAIN_ID; domains = g_hash_table_new_full( g_int_hash, g_int_equal, NULL, g_free ); /* TODO: Have a default openhpiclient.conf file in /etc */ oh_load_client_config(OH_CLIENT_DEFAULT_CONF, domains); /* Check to see if a default domain exists, if not, add it */ domain_conf = (struct oh_domain_conf *)g_hash_table_lookup(domains, &default_did); if (!domain_conf) { const char *host, *portstr; int port; /* TODO: change these envs to have DEFAULT in the name*/ host = getenv("OPENHPI_DAEMON_HOST"); if (!host) host = "localhost"; portstr = getenv("OPENHI_DAEMON_PORT"); if (!portstr) port = OPENHPI_DEFAULT_DAEMON_PORT; else port = atoi(portstr); domain_conf = g_new0(struct oh_domain_conf, 1); domain_conf->did = default_did; strncpy(domain_conf->host, host, SAHPI_MAX_TEXT_BUFFER_LENGTH); domain_conf->port = port; g_hash_table_insert(domains, &domain_conf->did, domain_conf); } g_static_rec_mutex_unlock(&sessions_sem); } g_static_rec_mutex_unlock(&sessions_sem); return 0; } SaErrorT oh_create_connx(SaHpiDomainIdT did, pcstrmsock *pinst) { struct oh_domain_conf *domain_conf = NULL; pcstrmsock connx = NULL; if (!pinst) { return SA_ERR_HPI_INVALID_PARAMS; } oh_client_init(); /* Initialize library - Will run only once */ g_static_rec_mutex_lock(&sessions_sem); connx = new cstrmsock; if (!connx) { g_static_rec_mutex_unlock(&sessions_sem); return SA_ERR_HPI_INTERNAL_ERROR; } domain_conf = (struct oh_domain_conf *)g_hash_table_lookup(domains, &did); if (!domain_conf) { delete connx; g_static_rec_mutex_unlock(&sessions_sem); err("Client configuration for domain %u was not found.", did); return SA_ERR_HPI_INVALID_DOMAIN; } g_static_rec_mutex_unlock(&sessions_sem); if (connx->Open(domain_conf->host, domain_conf->port)) { err("Could not open client socket" "\nPossibly, the OpenHPI daemon has not been started."); delete connx; return SA_ERR_HPI_NO_RESPONSE; } *pinst = connx; dbg("Client instance created"); return SA_OK; } void oh_delete_connx(pcstrmsock pinst) { if (pinst) { pinst->Close(); dbg("Connection closed and deleted"); delete pinst; } } SaErrorT oh_close_connx(SaHpiSessionIdT SessionId) { pthread_t thread_id = pthread_self(); struct oh_client_session *client_session = NULL; if (SessionId == 0) return SA_ERR_HPI_INVALID_PARAMS; g_static_rec_mutex_lock(&sessions_sem); client_session = (struct oh_client_session *)g_hash_table_lookup(sessions, &SessionId); if (!client_session) { g_static_rec_mutex_unlock(&sessions_sem); err("Did not find connx for sid %d", SessionId); return SA_ERR_HPI_INTERNAL_ERROR; } g_hash_table_remove(client_session->connxs, &thread_id); g_static_rec_mutex_unlock(&sessions_sem); return SA_OK; } SaErrorT oh_get_connx(SaHpiSessionIdT csid, SaHpiSessionIdT *dsid, pcstrmsock *pinst) { pthread_t thread_id = pthread_self(); struct oh_client_session *client_session = NULL; pcstrmsock connx = NULL; SaErrorT ret = SA_OK; if (!csid || !dsid || !pinst) return SA_ERR_HPI_INVALID_PARAMS; oh_client_init(); /* Initialize library - Will run only once */ // Look up connection table. If it exists, look up connection. // if there is not connection, create one on-the-fly. g_static_rec_mutex_lock(&sessions_sem); client_session = (struct oh_client_session *)g_hash_table_lookup(sessions, &csid); if (client_session) { connx = (pcstrmsock)g_hash_table_lookup(client_session->connxs, &thread_id); if (!connx) { ret = oh_create_connx(client_session->did, &connx); if (connx) { g_hash_table_insert(client_session->connxs, g_memdup(&thread_id, sizeof(pthread_t)), connx); dbg("We are inserting a new connection" " in conns table"); } } *dsid = client_session->dsid; *pinst = connx; } g_static_rec_mutex_unlock(&sessions_sem); if (client_session) { if (connx) return SA_OK; else return ret; } else return SA_ERR_HPI_INVALID_SESSION; } static void __delete_connx(gpointer data) { pcstrmsock pinst = (pcstrmsock)data; oh_delete_connx(pinst); } SaHpiSessionIdT oh_open_session(SaHpiDomainIdT did, SaHpiSessionIdT sid, pcstrmsock pinst) { GHashTable *connxs = NULL; pthread_t thread_id; struct oh_client_session *client_session; if (!sid || !pinst) return 0; client_session = g_new0(struct oh_client_session, 1); g_static_rec_mutex_lock(&sessions_sem); // Create connections table for new session. connxs = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, __delete_connx); // Map connection to thread id thread_id = pthread_self(); g_hash_table_insert(connxs, g_memdup(&thread_id, sizeof(pthread_t)), pinst); // Map connecitons table to session id client_session->did = did; client_session->dsid = sid; client_session->csid = next_client_sid++; client_session->connxs = connxs; g_hash_table_insert(sessions, &client_session->csid, client_session); g_static_rec_mutex_unlock(&sessions_sem); return client_session->csid; } SaErrorT oh_close_session(SaHpiSessionIdT SessionId) { if (SessionId == 0) return SA_ERR_HPI_INVALID_PARAMS; g_static_rec_mutex_lock(&sessions_sem); // Since we used g_hash_table_new_full to create the tables, // this will remove the connection hash table and all of its entries also. g_hash_table_remove(sessions, &SessionId); g_static_rec_mutex_unlock(&sessions_sem); return SA_OK; } --- NEW FILE: oh_client_session.h --- /* -*- linux-c -*- * * (C) Copyright IBM Corp. 2004-2008 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * W. David Ashley <da...@us...> * Renier Morales <re...@op...> * */ #ifndef __OH_CLIENT_SESSION_H #define __OH_CLIENT_SESSION_H #include "strmsock.h" extern "C" { #include <glib.h> #include <SaHpi.h> } struct oh_client_session { SaHpiDomainIdT did; /* Domain Id */ SaHpiSessionIdT csid; /* Client Session Id */ SaHpiSessionIdT dsid; /* Domain Session Id */ GHashTable *connxs; /* Connections for this session (per thread) */ }; extern GHashTable *domains; extern GHashTable *sessions; extern GStaticRecMutex sessions_sem; SaErrorT oh_create_connx(SaHpiDomainIdT, pcstrmsock *); void oh_delete_connx(pcstrmsock); SaErrorT oh_close_connx(SaHpiSessionIdT); SaErrorT oh_get_connx(SaHpiSessionIdT, SaHpiSessionIdT *, pcstrmsock *); SaHpiSessionIdT oh_open_session(SaHpiDomainIdT, SaHpiSessionIdT, pcstrmsock); SaErrorT oh_close_session(SaHpiSessionIdT); #endif /* __OH_CLIENT_SESSION_H */ |