xref: /onnv-gate/usr/src/lib/libtsalarm/common/tsalarm.c (revision 12241:3b141d2cfb92)
14975Swillard /*
24975Swillard  * CDDL HEADER START
34975Swillard  *
44975Swillard  * The contents of this file are subject to the terms of the
54975Swillard  * Common Development and Distribution License (the "License").
64975Swillard  * You may not use this file except in compliance with the License.
74975Swillard  *
84975Swillard  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94975Swillard  * or http://www.opensolaris.org/os/licensing.
104975Swillard  * See the License for the specific language governing permissions
114975Swillard  * and limitations under the License.
124975Swillard  *
134975Swillard  * When distributing Covered Code, include this CDDL HEADER in each
144975Swillard  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154975Swillard  * If applicable, add the following below this CDDL HEADER, with the
164975Swillard  * fields enclosed by brackets "[]" replaced with your own identifying
174975Swillard  * information: Portions Copyright [yyyy] [name of copyright owner]
184975Swillard  *
194975Swillard  * CDDL HEADER END
204975Swillard  */
214975Swillard /*
22*12241Scarl.chesbrough@sun.com  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
234975Swillard  */
244975Swillard 
254975Swillard /*
264975Swillard  * Telco-alarm library, which communicates through libpcp to set/get
274975Swillard  * alarms.
284975Swillard  */
294975Swillard 
304975Swillard #include <stdio.h>
314975Swillard #include <stdlib.h>
324975Swillard #include <sys/types.h>
334975Swillard #include <unistd.h>
344975Swillard #include <libpcp.h>
354975Swillard 
364975Swillard #include "tsalarm.h"
374975Swillard 
384975Swillard /* Message Types */
394975Swillard #define	TSALARM_CONTROL		15
404975Swillard #define	TSALARM_CONTROL_R	16
414975Swillard 
424975Swillard #define	TSALARM_CHANNEL_TIMEOUT	20
434975Swillard #define	TSALARM_MAX_RETRIES	3
444975Swillard #define	TSALARM_SERVICE_NAME	"SUNW,sun4v-telco-alarm"
454975Swillard 
464975Swillard int
tsalarm_get(uint32_t alarm_type,uint32_t * alarm_state)474975Swillard tsalarm_get(uint32_t alarm_type, uint32_t *alarm_state)
484975Swillard {
494975Swillard 	int		chnl_fd;
504975Swillard 	tsalarm_req_t	*req_ptr = NULL;
514975Swillard 	tsalarm_resp_t	*resp_ptr = NULL;
524975Swillard 	pcp_msg_t	send_msg;
534975Swillard 	pcp_msg_t	recv_msg;
544975Swillard 	int		rc = TSALARM_SUCCESS;
554975Swillard 	int		retries;
564975Swillard 
574975Swillard 	/* initialize virtual channel */
584975Swillard 	for (retries = 1; retries <= TSALARM_MAX_RETRIES; retries++) {
594975Swillard 		if ((chnl_fd = pcp_init(TSALARM_SERVICE_NAME)) < 0) {
604975Swillard 			if (retries == TSALARM_MAX_RETRIES) {
614975Swillard 				rc = TSALARM_CHANNEL_INIT_FAILURE;
624975Swillard 				goto cleanup;
634975Swillard 			}
644975Swillard 			(void) sleep(TSALARM_CHANNEL_TIMEOUT);
654975Swillard 		} else
664975Swillard 			break;
674975Swillard 	}
684975Swillard 
694975Swillard 	/* create request message data */
704975Swillard 	req_ptr = malloc(sizeof (tsalarm_req_t));
714975Swillard 	if (req_ptr == NULL) {
724975Swillard 		rc = TSALARM_NULL_REQ_DATA;
734975Swillard 		goto cleanup;
744975Swillard 	}
754975Swillard 	req_ptr->alarm_action = TSALARM_STATUS;
764975Swillard 	req_ptr->alarm_id = alarm_type;
774975Swillard 
784975Swillard 	send_msg.msg_type = TSALARM_CONTROL;
794975Swillard 	send_msg.sub_type = NULL;
804975Swillard 	send_msg.msg_len = sizeof (tsalarm_req_t);
814975Swillard 	send_msg.msg_data = (uint8_t *)req_ptr;
824975Swillard 
834975Swillard 	/*
844975Swillard 	 * Send the request and receive the response.
854975Swillard 	 */
864975Swillard 	if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
874975Swillard 	    TSALARM_CHANNEL_TIMEOUT) < 0) {
884975Swillard 		/* we either timed out or erred; either way try again */
894975Swillard 		(void) sleep(TSALARM_CHANNEL_TIMEOUT);
904975Swillard 
914975Swillard 		if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
924975Swillard 		    TSALARM_CHANNEL_TIMEOUT) < 0) {
934975Swillard 			rc = TSALARM_COMM_FAILURE;
944975Swillard 			goto cleanup;
954975Swillard 		}
964975Swillard 	}
974975Swillard 
984975Swillard 	/*
99*12241Scarl.chesbrough@sun.com 	 * verify that the Alarm action has taken place
100*12241Scarl.chesbrough@sun.com 	 */
101*12241Scarl.chesbrough@sun.com 	if ((resp_ptr = (tsalarm_resp_t *)recv_msg.msg_data) == NULL)
102*12241Scarl.chesbrough@sun.com 		goto cleanup;
103*12241Scarl.chesbrough@sun.com 
104*12241Scarl.chesbrough@sun.com 	/*
1054975Swillard 	 * validate that this data was meant for us
1064975Swillard 	 */
1074975Swillard 	if (recv_msg.msg_type != TSALARM_CONTROL_R) {
1084975Swillard 		rc = TSALARM_UNBOUND_PACKET_RECVD;
1094975Swillard 		goto cleanup;
1104975Swillard 	}
1114975Swillard 
1124975Swillard 	if (resp_ptr->status == TSALARM_ERROR) {
1134975Swillard 		rc = TSALARM_GET_ERROR;
1144975Swillard 		goto cleanup;
1154975Swillard 	}
1164975Swillard 
1174975Swillard 	if (resp_ptr->alarm_state == TSALARM_STATE_UNKNOWN) {
1184975Swillard 		rc = TSALARM_GET_ERROR;
1194975Swillard 		goto cleanup;
1204975Swillard 	}
1214975Swillard 
1224975Swillard 	*alarm_state = resp_ptr->alarm_state;
1234975Swillard 
1244975Swillard cleanup:
1254975Swillard 	if (req_ptr != NULL)
1264975Swillard 		free(req_ptr);
127*12241Scarl.chesbrough@sun.com 
128*12241Scarl.chesbrough@sun.com 	/* free recv_msg.msg_data through pointer to make sure it is valid */
129*12241Scarl.chesbrough@sun.com 	if (resp_ptr != NULL)
130*12241Scarl.chesbrough@sun.com 		free(resp_ptr);
1314975Swillard 
1324975Swillard 	/* close virtual channel fd */
1334975Swillard 	(void) pcp_close(chnl_fd);
1344975Swillard 
1354975Swillard 	return (rc);
1364975Swillard }
1374975Swillard 
1384975Swillard int
tsalarm_set(uint32_t alarm_type,uint32_t alarm_state)1394975Swillard tsalarm_set(uint32_t alarm_type, uint32_t alarm_state)
1404975Swillard {
1414975Swillard 	int		chnl_fd;
1424975Swillard 	tsalarm_req_t   *req_ptr = NULL;
1434975Swillard 	tsalarm_resp_t  *resp_ptr = NULL;
1444975Swillard 	pcp_msg_t	send_msg;
1454975Swillard 	pcp_msg_t	recv_msg;
1464975Swillard 	int		rc = TSALARM_SUCCESS;
1474975Swillard 	int		retries;
1484975Swillard 
1494975Swillard 	/* initialize virtual channel */
1504975Swillard 	for (retries = 1; retries <= TSALARM_MAX_RETRIES; retries++) {
1514975Swillard 		if ((chnl_fd = pcp_init(TSALARM_SERVICE_NAME)) < 0) {
1524975Swillard 			if (retries == TSALARM_MAX_RETRIES) {
1534975Swillard 				rc = TSALARM_CHANNEL_INIT_FAILURE;
1544975Swillard 				goto cleanup;
1554975Swillard 			}
1564975Swillard 			(void) sleep(TSALARM_CHANNEL_TIMEOUT);
1574975Swillard 		} else
1584975Swillard 			break;
1594975Swillard 	}
1604975Swillard 
1614975Swillard 	/* create request message data */
1624975Swillard 	req_ptr = malloc(sizeof (tsalarm_req_t));
1634975Swillard 	if (req_ptr == NULL) {
1644975Swillard 		rc = TSALARM_NULL_REQ_DATA;
1654975Swillard 		goto cleanup;
1664975Swillard 	}
1674975Swillard 	req_ptr->alarm_id = alarm_type;
1684975Swillard 	if (alarm_state == TSALARM_STATE_ON)
1694975Swillard 		req_ptr->alarm_action = TSALARM_ENABLE;
1704975Swillard 	else if (alarm_state == TSALARM_STATE_OFF)
1714975Swillard 		req_ptr->alarm_action = TSALARM_DISABLE;
1724975Swillard 
1734975Swillard 	send_msg.msg_type = TSALARM_CONTROL;
1744975Swillard 	send_msg.sub_type = NULL;
1754975Swillard 	send_msg.msg_len = sizeof (tsalarm_req_t);
1764975Swillard 	send_msg.msg_data = (uint8_t *)req_ptr;
1774975Swillard 
1784975Swillard 	/*
1794975Swillard 	 * Send the request and receive the response.
1804975Swillard 	 */
1814975Swillard 	if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
1824975Swillard 	    TSALARM_CHANNEL_TIMEOUT) < 0) {
1834975Swillard 		/* we either timed out or erred; either way try again */
1844975Swillard 		(void) sleep(TSALARM_CHANNEL_TIMEOUT);
1854975Swillard 
1864975Swillard 		if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
1874975Swillard 		    TSALARM_CHANNEL_TIMEOUT) < 0) {
1884975Swillard 			rc = TSALARM_COMM_FAILURE;
1894975Swillard 			goto cleanup;
1904975Swillard 		}
1914975Swillard 	}
1924975Swillard 
1934975Swillard 	/*
194*12241Scarl.chesbrough@sun.com 	 * verify that the Alarm action has taken place
195*12241Scarl.chesbrough@sun.com 	 */
196*12241Scarl.chesbrough@sun.com 	if ((resp_ptr = (tsalarm_resp_t *)recv_msg.msg_data) == NULL)
197*12241Scarl.chesbrough@sun.com 		goto cleanup;
198*12241Scarl.chesbrough@sun.com 
199*12241Scarl.chesbrough@sun.com 	/*
2004975Swillard 	 * validate that this data was meant for us
2014975Swillard 	 */
2024975Swillard 	if (recv_msg.msg_type != TSALARM_CONTROL_R) {
2034975Swillard 		rc = TSALARM_UNBOUND_PACKET_RECVD;
2044975Swillard 		goto cleanup;
2054975Swillard 	}
2064975Swillard 
2074975Swillard 	if (resp_ptr->status == TSALARM_ERROR) {
2084975Swillard 		rc = TSALARM_SET_ERROR;
2094975Swillard 		goto cleanup;
2104975Swillard 	}
2114975Swillard 
2124975Swillard 	/*
2134975Swillard 	 * ensure the Alarm action taken is the one requested
2144975Swillard 	 */
2154975Swillard 	if ((req_ptr->alarm_action == TSALARM_DISABLE) &&
2164975Swillard 	    (resp_ptr->alarm_state != TSALARM_STATE_OFF)) {
2174975Swillard 		rc = TSALARM_SET_ERROR;
2184975Swillard 		goto cleanup;
2194975Swillard 	} else if ((req_ptr->alarm_action == TSALARM_ENABLE) &&
2204975Swillard 	    (resp_ptr->alarm_state != TSALARM_STATE_ON)) {
2214975Swillard 		rc = TSALARM_SET_ERROR;
2224975Swillard 		goto cleanup;
2234975Swillard 	} else if (resp_ptr->alarm_state == TSALARM_STATE_UNKNOWN) {
2244975Swillard 		rc = TSALARM_SET_ERROR;
2254975Swillard 		goto cleanup;
2264975Swillard 	}
2274975Swillard 
2284975Swillard cleanup:
2294975Swillard 	if (req_ptr != NULL)
2304975Swillard 		free(req_ptr);
231*12241Scarl.chesbrough@sun.com 
232*12241Scarl.chesbrough@sun.com 	/* free recv_msg.msg_data through pointer to make sure it is valid */
233*12241Scarl.chesbrough@sun.com 	if (resp_ptr != NULL)
234*12241Scarl.chesbrough@sun.com 		free(resp_ptr);
2354975Swillard 
2364975Swillard 	/* close virtual channel fd */
2374975Swillard 	(void) pcp_close(chnl_fd);
2384975Swillard 
2394975Swillard 	return (rc);
2404975Swillard }
241