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
;
128 /* free recv_msg.msg_data through pointer to make sure it is valid */
129 if (resp_ptr
!= NULL
)
132 /* close virtual channel fd */
133 (void) pcp_close(chnl_fd
);
139 tsalarm_set(uint32_t alarm_type
, uint32_t alarm_state
)
142 tsalarm_req_t
*req_ptr
= NULL
;
143 tsalarm_resp_t
*resp_ptr
= NULL
;
146 int rc
= TSALARM_SUCCESS
;
149 /* initialize virtual channel */
150 for (retries
= 1; retries
<= TSALARM_MAX_RETRIES
; retries
++) {
151 if ((chnl_fd
= pcp_init(TSALARM_SERVICE_NAME
)) < 0) {
152 if (retries
== TSALARM_MAX_RETRIES
) {
153 rc
= TSALARM_CHANNEL_INIT_FAILURE
;
156 (void) sleep(TSALARM_CHANNEL_TIMEOUT
);
161 /* create request message data */
162 req_ptr
= malloc(sizeof (tsalarm_req_t
));
163 if (req_ptr
== NULL
) {
164 rc
= TSALARM_NULL_REQ_DATA
;
167 req_ptr
->alarm_id
= alarm_type
;
168 if (alarm_state
== TSALARM_STATE_ON
)
169 req_ptr
->alarm_action
= TSALARM_ENABLE
;
170 else if (alarm_state
== TSALARM_STATE_OFF
)
171 req_ptr
->alarm_action
= TSALARM_DISABLE
;
173 send_msg
.msg_type
= TSALARM_CONTROL
;
174 send_msg
.sub_type
= NULL
;
175 send_msg
.msg_len
= sizeof (tsalarm_req_t
);
176 send_msg
.msg_data
= (uint8_t *)req_ptr
;
179 * Send the request and receive the response.
181 if (pcp_send_recv(chnl_fd
, &send_msg
, &recv_msg
,
182 TSALARM_CHANNEL_TIMEOUT
) < 0) {
183 /* we either timed out or erred; either way try again */
184 (void) sleep(TSALARM_CHANNEL_TIMEOUT
);
186 if (pcp_send_recv(chnl_fd
, &send_msg
, &recv_msg
,
187 TSALARM_CHANNEL_TIMEOUT
) < 0) {
188 rc
= TSALARM_COMM_FAILURE
;
194 * verify that the Alarm action has taken place
196 if ((resp_ptr
= (tsalarm_resp_t
*)recv_msg
.msg_data
) == NULL
)
200 * validate that this data was meant for us
202 if (recv_msg
.msg_type
!= TSALARM_CONTROL_R
) {
203 rc
= TSALARM_UNBOUND_PACKET_RECVD
;
207 if (resp_ptr
->status
== TSALARM_ERROR
) {
208 rc
= TSALARM_SET_ERROR
;
213 * ensure the Alarm action taken is the one requested
215 if ((req_ptr
->alarm_action
== TSALARM_DISABLE
) &&
216 (resp_ptr
->alarm_state
!= TSALARM_STATE_OFF
)) {
217 rc
= TSALARM_SET_ERROR
;
219 } else if ((req_ptr
->alarm_action
== TSALARM_ENABLE
) &&
220 (resp_ptr
->alarm_state
!= TSALARM_STATE_ON
)) {
221 rc
= TSALARM_SET_ERROR
;
223 } else if (resp_ptr
->alarm_state
== TSALARM_STATE_UNKNOWN
) {
224 rc
= TSALARM_SET_ERROR
;
232 /* free recv_msg.msg_data through pointer to make sure it is valid */
233 if (resp_ptr
!= NULL
)
236 /* close virtual channel fd */
237 (void) pcp_close(chnl_fd
);