4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Telco-alarm library, which communicates through libpcp to set/get
32 #include <sys/types.h>
39 #define TSALARM_CONTROL 15
40 #define TSALARM_CONTROL_R 16
42 #define TSALARM_CHANNEL_TIMEOUT 20
43 #define TSALARM_MAX_RETRIES 3
44 #define TSALARM_SERVICE_NAME "SUNW,sun4v-telco-alarm"
47 tsalarm_get(uint32_t alarm_type
, uint32_t *alarm_state
)
50 tsalarm_req_t
*req_ptr
= NULL
;
51 tsalarm_resp_t
*resp_ptr
= NULL
;
54 int rc
= TSALARM_SUCCESS
;
57 /* initialize virtual channel */
58 for (retries
= 1; retries
<= TSALARM_MAX_RETRIES
; retries
++) {
59 if ((chnl_fd
= pcp_init(TSALARM_SERVICE_NAME
)) < 0) {
60 if (retries
== TSALARM_MAX_RETRIES
) {
61 rc
= TSALARM_CHANNEL_INIT_FAILURE
;
64 (void) sleep(TSALARM_CHANNEL_TIMEOUT
);
69 /* create request message data */
70 req_ptr
= malloc(sizeof (tsalarm_req_t
));
71 if (req_ptr
== NULL
) {
72 rc
= TSALARM_NULL_REQ_DATA
;
75 req_ptr
->alarm_action
= TSALARM_STATUS
;
76 req_ptr
->alarm_id
= alarm_type
;
78 send_msg
.msg_type
= TSALARM_CONTROL
;
79 send_msg
.sub_type
= NULL
;
80 send_msg
.msg_len
= sizeof (tsalarm_req_t
);
81 send_msg
.msg_data
= (uint8_t *)req_ptr
;
84 * Send the request and receive the response.
86 if (pcp_send_recv(chnl_fd
, &send_msg
, &recv_msg
,
87 TSALARM_CHANNEL_TIMEOUT
) < 0) {
88 /* we either timed out or erred; either way try again */
89 (void) sleep(TSALARM_CHANNEL_TIMEOUT
);
91 if (pcp_send_recv(chnl_fd
, &send_msg
, &recv_msg
,
92 TSALARM_CHANNEL_TIMEOUT
) < 0) {
93 rc
= TSALARM_COMM_FAILURE
;
99 * verify that the Alarm action has taken place
101 if ((resp_ptr
= (tsalarm_resp_t
*)recv_msg
.msg_data
) == NULL
)
105 * validate that this data was meant for us
107 if (recv_msg
.msg_type
!= TSALARM_CONTROL_R
) {
108 rc
= TSALARM_UNBOUND_PACKET_RECVD
;
112 if (resp_ptr
->status
== TSALARM_ERROR
) {
113 rc
= TSALARM_GET_ERROR
;
117 if (resp_ptr
->alarm_state
== TSALARM_STATE_UNKNOWN
) {
118 rc
= TSALARM_GET_ERROR
;
122 *alarm_state
= resp_ptr
->alarm_state
;
127 /* free recv_msg.msg_data through pointer to make sure it is valid */
130 /* close virtual channel fd */
131 (void) pcp_close(chnl_fd
);
137 tsalarm_set(uint32_t alarm_type
, uint32_t alarm_state
)
140 tsalarm_req_t
*req_ptr
= NULL
;
141 tsalarm_resp_t
*resp_ptr
= NULL
;
144 int rc
= TSALARM_SUCCESS
;
147 /* initialize virtual channel */
148 for (retries
= 1; retries
<= TSALARM_MAX_RETRIES
; retries
++) {
149 if ((chnl_fd
= pcp_init(TSALARM_SERVICE_NAME
)) < 0) {
150 if (retries
== TSALARM_MAX_RETRIES
) {
151 rc
= TSALARM_CHANNEL_INIT_FAILURE
;
154 (void) sleep(TSALARM_CHANNEL_TIMEOUT
);
159 /* create request message data */
160 req_ptr
= malloc(sizeof (tsalarm_req_t
));
161 if (req_ptr
== NULL
) {
162 rc
= TSALARM_NULL_REQ_DATA
;
165 req_ptr
->alarm_id
= alarm_type
;
166 if (alarm_state
== TSALARM_STATE_ON
)
167 req_ptr
->alarm_action
= TSALARM_ENABLE
;
168 else if (alarm_state
== TSALARM_STATE_OFF
)
169 req_ptr
->alarm_action
= TSALARM_DISABLE
;
171 send_msg
.msg_type
= TSALARM_CONTROL
;
172 send_msg
.sub_type
= NULL
;
173 send_msg
.msg_len
= sizeof (tsalarm_req_t
);
174 send_msg
.msg_data
= (uint8_t *)req_ptr
;
177 * Send the request and receive the response.
179 if (pcp_send_recv(chnl_fd
, &send_msg
, &recv_msg
,
180 TSALARM_CHANNEL_TIMEOUT
) < 0) {
181 /* we either timed out or erred; either way try again */
182 (void) sleep(TSALARM_CHANNEL_TIMEOUT
);
184 if (pcp_send_recv(chnl_fd
, &send_msg
, &recv_msg
,
185 TSALARM_CHANNEL_TIMEOUT
) < 0) {
186 rc
= TSALARM_COMM_FAILURE
;
192 * verify that the Alarm action has taken place
194 if ((resp_ptr
= (tsalarm_resp_t
*)recv_msg
.msg_data
) == NULL
)
198 * validate that this data was meant for us
200 if (recv_msg
.msg_type
!= TSALARM_CONTROL_R
) {
201 rc
= TSALARM_UNBOUND_PACKET_RECVD
;
205 if (resp_ptr
->status
== TSALARM_ERROR
) {
206 rc
= TSALARM_SET_ERROR
;
211 * ensure the Alarm action taken is the one requested
213 if ((req_ptr
->alarm_action
== TSALARM_DISABLE
) &&
214 (resp_ptr
->alarm_state
!= TSALARM_STATE_OFF
)) {
215 rc
= TSALARM_SET_ERROR
;
217 } else if ((req_ptr
->alarm_action
== TSALARM_ENABLE
) &&
218 (resp_ptr
->alarm_state
!= TSALARM_STATE_ON
)) {
219 rc
= TSALARM_SET_ERROR
;
221 } else if (resp_ptr
->alarm_state
== TSALARM_STATE_UNKNOWN
) {
222 rc
= TSALARM_SET_ERROR
;
229 /* free recv_msg.msg_data through pointer to make sure it is valid */
232 /* close virtual channel fd */
233 (void) pcp_close(chnl_fd
);