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]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 /* $Id: write.c 146 2006-03-24 00:26:54Z njacobs $ */
30 #pragma ident "%Z%%M% %I% %E% SMI"
35 #include <sys/types.h>
36 #include <netinet/in.h>
43 papi_attribute_to_ipp_type(papi_attribute_value_type_t type
)
47 return (VTAG_INTEGER
);
49 return (VTAG_BOOLEAN
);
51 return (VTAG_RANGE_OF_INTEGER
);
53 return (VTAG_RESOLUTION
);
55 return (VTAG_DATE_TIME
);
57 return (VTAG_TEXT_WITHOUT_LANGUAGE
);
64 papi_ipp_type_match(papi_attribute_value_type_t papi
, int8_t ipp
)
70 case VTAG_OCTET_STRING
:
71 case VTAG_TEXT_WITHOUT_LANGUAGE
:
74 case VTAG_NATURAL_LANGUAGE
:
75 case VTAG_MIME_MEDIA_TYPE
:
76 case VTAG_NAME_WITHOUT_LANGUAGE
:
80 return (PAPI_CONFLICT
);
89 return (PAPI_CONFLICT
);
93 if (ipp
!= VTAG_BOOLEAN
)
94 return (PAPI_CONFLICT
);
97 if (ipp
!= VTAG_RANGE_OF_INTEGER
)
98 return (PAPI_CONFLICT
);
100 case PAPI_RESOLUTION
:
101 if (ipp
!= VTAG_RESOLUTION
)
102 return (PAPI_CONFLICT
);
105 if (ipp
!= VTAG_DATE_TIME
)
106 return (PAPI_CONFLICT
);
108 case PAPI_COLLECTION
:
109 /* don't need to match */
117 ipp_write_attribute(ipp_writer_t iwrite
, void *fd
, papi_attribute_t
*attribute
)
119 papi_status_t status
;
120 papi_attribute_value_t
**values
;
125 name
= attribute
->name
;
126 values
= attribute
->values
;
128 if ((type
= name_to_ipp_type(name
)) == 0)
129 type
= papi_attribute_to_ipp_type(attribute
->type
);
131 /* The types don't match, so don't send the attribute */
132 if ((status
= papi_ipp_type_match(attribute
->type
, type
)) != PAPI_OK
)
135 if (values
== NULL
) {
138 type
= VTAG_UNSUPPORTED
;
139 if (iwrite(fd
, &type
, 1) != 1)
140 return (PAPI_DEVICE_ERROR
);
142 if (name
!= NULL
) { /* first value gets named */
143 length
= (uint16_t)htons(strlen(name
));
145 if (iwrite(fd
, &length
, 2) != 2)
146 return (PAPI_DEVICE_ERROR
);
147 if (iwrite(fd
, name
, strlen(name
)) != strlen(name
))
148 return (PAPI_DEVICE_ERROR
);
151 length
= (uint16_t)htons(0);
152 if (iwrite(fd
, &length
, 2) != 2)
153 return (PAPI_DEVICE_ERROR
);
160 for (i
= 0; values
[i
] != NULL
; i
++) {
161 papi_attribute_value_t
*value
= values
[i
];
164 if (iwrite(fd
, &type
, 1) != 1)
165 return (PAPI_DEVICE_ERROR
);
167 if (name
!= NULL
) { /* first value gets named */
168 length
= (uint16_t)htons(strlen(name
));
170 if (iwrite(fd
, &length
, 2) != 2)
171 return (PAPI_DEVICE_ERROR
);
172 if (iwrite(fd
, name
, strlen(name
)) != strlen(name
))
173 return (PAPI_DEVICE_ERROR
);
176 length
= (uint16_t)htons(0);
178 if (iwrite(fd
, &length
, 2) != 2)
179 return (PAPI_DEVICE_ERROR
);
182 switch (attribute
->type
) {
184 char *v
= (char *)value
->string
;
187 size_t str_length
= strlen(v
);
190 * if the length is more than 16 bits can
191 * express, send what can be represented
192 * in 16 bits. IPP "strings" can only be
195 if (str_length
> 0xFFFF)
198 length
= (uint16_t)htons(str_length
);
199 if (iwrite(fd
, &length
, 2) != 2)
200 return (PAPI_DEVICE_ERROR
);
201 if (iwrite(fd
, v
, str_length
) != str_length
)
202 return (PAPI_DEVICE_ERROR
);
204 if (iwrite(fd
, &length
, 2) != 2)
205 return (PAPI_DEVICE_ERROR
);
209 int8_t v
= (int8_t)value
->boolean
;
211 length
= (uint16_t)htons(1);
212 if (iwrite(fd
, &length
, 2) != 2)
213 return (PAPI_DEVICE_ERROR
);
214 if (iwrite(fd
, &v
, 1) != 1)
215 return (PAPI_DEVICE_ERROR
);
219 int32_t v
= (int32_t)value
->integer
;
221 length
= (uint16_t)htons(4);
222 v
= (int32_t)htonl(v
);
223 if (iwrite(fd
, &length
, 2) != 2)
224 return (PAPI_DEVICE_ERROR
);
225 if (iwrite(fd
, &v
, 4) != 4)
226 return (PAPI_DEVICE_ERROR
);
230 int32_t min
= (int32_t)htonl((int)(value
->range
).lower
),
231 max
= (int32_t)htonl((int)(value
->range
).upper
);
233 length
= (uint16_t)htons(8);
234 if (iwrite(fd
, &length
, 2) != 2)
235 return (PAPI_DEVICE_ERROR
);
236 if (iwrite(fd
, &min
, 4) != 4)
237 return (PAPI_DEVICE_ERROR
);
238 if (iwrite(fd
, &max
, 4) != 4)
239 return (PAPI_DEVICE_ERROR
);
242 case PAPI_RESOLUTION
: {
243 int32_t x
= (int)(value
->resolution
).xres
,
244 y
= (int)(value
->resolution
).yres
;
245 int8_t units
= (int8_t)(value
->resolution
).units
;
247 length
= (uint16_t)htons(9);
248 x
= (int32_t)htonl(x
);
249 y
= (int32_t)htonl(y
);
251 if (iwrite(fd
, &length
, 2) != 2)
252 return (PAPI_DEVICE_ERROR
);
253 if (iwrite(fd
, &x
, 4) != 4)
254 return (PAPI_DEVICE_ERROR
);
255 if (iwrite(fd
, &y
, 4) != 4)
256 return (PAPI_DEVICE_ERROR
);
257 if (iwrite(fd
, &units
, 1) != 1)
258 return (PAPI_DEVICE_ERROR
);
261 case PAPI_DATETIME
: {
262 struct tm
*v
= gmtime(&value
->datetime
);
266 length
= (uint16_t)htons(11);
267 if (iwrite(fd
, &length
, 2) != 2)
268 return (PAPI_DEVICE_ERROR
);
269 s
= (uint16_t)htons(v
->tm_year
+ 1900);
270 if (iwrite(fd
, &s
, 2) != 2)
271 return (PAPI_DEVICE_ERROR
);
273 if (iwrite(fd
, &c
, 1) != 1)
274 return (PAPI_DEVICE_ERROR
);
276 if (iwrite(fd
, &c
, 1) != 1)
277 return (PAPI_DEVICE_ERROR
);
279 if (iwrite(fd
, &c
, 1) != 1)
280 return (PAPI_DEVICE_ERROR
);
282 if (iwrite(fd
, &c
, 1) != 1)
283 return (PAPI_DEVICE_ERROR
);
285 if (iwrite(fd
, &c
, 1) != 1)
286 return (PAPI_DEVICE_ERROR
);
287 c
= /* v->deciseconds */ 0;
288 if (iwrite(fd
, &c
, 1) != 1)
289 return (PAPI_DEVICE_ERROR
);
290 c
= /* v->utc_dir */ 0;
291 if (iwrite(fd
, &c
, 1) != 1)
292 return (PAPI_DEVICE_ERROR
);
293 c
= /* v->utc_hours */ 0;
294 if (iwrite(fd
, &c
, 1) != 1)
295 return (PAPI_DEVICE_ERROR
);
296 c
= /* v->utc_minutes */ 0;
297 if (iwrite(fd
, &c
, 1) != 1)
298 return (PAPI_DEVICE_ERROR
);
303 * If there is a value, it is not one of our
304 * types, so we couldn't use it anyway. We assume
305 * that it was an OOB type with no value
307 length
= (uint16_t)htons(0);
308 if (iwrite(fd
, &length
, 2) != 2)
309 return (PAPI_DEVICE_ERROR
);
319 ipp_write_attribute_group(ipp_writer_t iwrite
, void *fd
, int8_t type
,
320 papi_attribute_t
**attributes
)
322 papi_status_t result
= PAPI_OK
;
325 /* write group tag */
326 if (iwrite(fd
, &type
, 1) != 1)
327 return (PAPI_DEVICE_ERROR
);
330 for (i
= 0; ((attributes
[i
] != NULL
) && (result
== PAPI_OK
)); i
++)
331 result
= ipp_write_attribute(iwrite
, fd
, attributes
[i
]);
337 ipp_write_attribute_groups(ipp_writer_t iwrite
, void *fd
,
338 papi_attribute_t
**groups
)
340 papi_status_t result
= PAPI_OK
;
343 for (c
= DTAG_MIN
; c
<= DTAG_MAX
; c
++) {
344 papi_status_t status
;
345 papi_attribute_t
**group
= NULL
;
349 (void) ipp_tag_string(c
, name
, sizeof (name
));
350 for (status
= papiAttributeListGetCollection(groups
, &iter
,
352 ((status
== PAPI_OK
) && (result
== PAPI_OK
));
353 status
= papiAttributeListGetCollection(groups
, &iter
,
355 result
= ipp_write_attribute_group(iwrite
, fd
,
359 c
= DTAG_END_OF_ATTRIBUTES
;
360 if (iwrite(fd
, &c
, 1) != 1)
361 result
= PAPI_DEVICE_ERROR
;
367 ipp_write_message_header(ipp_writer_t iwrite
, void *fd
,
368 papi_attribute_t
**message
)
375 /* write the version */
376 papiAttributeListGetInteger(message
, NULL
, "version-major", &tmp
);
378 if (iwrite(fd
, &c
, 1) != 1)
379 return (PAPI_DEVICE_ERROR
);
381 papiAttributeListGetInteger(message
, NULL
, "version-minor", &tmp
);
383 if (iwrite(fd
, &c
, 1) != 1)
384 return (PAPI_DEVICE_ERROR
);
386 /* write the request/status code */
387 papiAttributeListGetInteger(message
, NULL
, "status-code", &tmp
);
388 papiAttributeListGetInteger(message
, NULL
, "operation-id", &tmp
);
389 s
= (uint16_t)htons(tmp
);
390 if (iwrite(fd
, &s
, 2) != 2)
391 return (PAPI_DEVICE_ERROR
);
393 /* write the request id */
394 papiAttributeListGetInteger(message
, NULL
, "request-id", &tmp
);
395 i
= (uint32_t)htonl(tmp
);
396 if (iwrite(fd
, &i
, 4) != 4)
397 return (PAPI_DEVICE_ERROR
);
403 ipp_write_message(ipp_writer_t iwrite
, void *fd
, papi_attribute_t
**message
)
405 papi_status_t result
;
407 if ((iwrite
== NULL
) || (fd
== NULL
) || (message
== NULL
))
408 return (PAPI_BAD_ARGUMENT
);
410 result
= ipp_write_message_header(iwrite
, fd
, message
);
411 if (result
== PAPI_OK
)
412 result
= ipp_write_attribute_groups(iwrite
, fd
, message
);