16ba597cAnurag S. Maskey/*
26ba597cAnurag S. Maskey * CDDL HEADER START
36ba597cAnurag S. Maskey *
46ba597cAnurag S. Maskey * The contents of this file are subject to the terms of the
56ba597cAnurag S. Maskey * Common Development and Distribution License (the "License").
66ba597cAnurag S. Maskey * You may not use this file except in compliance with the License.
76ba597cAnurag S. Maskey *
86ba597cAnurag S. Maskey * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597cAnurag S. Maskey * or http://www.opensolaris.org/os/licensing.
106ba597cAnurag S. Maskey * See the License for the specific language governing permissions
116ba597cAnurag S. Maskey * and limitations under the License.
126ba597cAnurag S. Maskey *
136ba597cAnurag S. Maskey * When distributing Covered Code, include this CDDL HEADER in each
146ba597cAnurag S. Maskey * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597cAnurag S. Maskey * If applicable, add the following below this CDDL HEADER, with the
166ba597cAnurag S. Maskey * fields enclosed by brackets "[]" replaced with your own identifying
176ba597cAnurag S. Maskey * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597cAnurag S. Maskey *
196ba597cAnurag S. Maskey * CDDL HEADER END
206ba597cAnurag S. Maskey */
216ba597cAnurag S. Maskey
226ba597cAnurag S. Maskey/*
2348fff0eRenee Danson Sommerfeld * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2433f5ff1Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
256ba597cAnurag S. Maskey */
266ba597cAnurag S. Maskey
276ba597cAnurag S. Maskey#include <assert.h>
286ba597cAnurag S. Maskey#include <stdio.h>
296ba597cAnurag S. Maskey#include <stdlib.h>
306ba597cAnurag S. Maskey#include <string.h>
316ba597cAnurag S. Maskey#include <sys/types.h>
326ba597cAnurag S. Maskey#include <libdlwlan.h>
336ba597cAnurag S. Maskey#include <libnvpair.h>
346ba597cAnurag S. Maskey
356ba597cAnurag S. Maskey#include "libnwam_impl.h"
366ba597cAnurag S. Maskey#include <libnwam_priv.h>
376ba597cAnurag S. Maskey#include <libnwam.h>
386ba597cAnurag S. Maskey
396ba597cAnurag S. Maskey/*
406ba597cAnurag S. Maskey * Internal implementation of libnwam in-memory objects and values.  Objects
416ba597cAnurag S. Maskey * are nvlists.
426ba597cAnurag S. Maskey */
436ba597cAnurag S. Maskey
446ba597cAnurag S. Maskeyvoid
456ba597cAnurag S. Maskeynwam_value_free(nwam_value_t value)
466ba597cAnurag S. Maskey{
476ba597cAnurag S. Maskey	uint_t i;
486ba597cAnurag S. Maskey
496ba597cAnurag S. Maskey	if (value == NULL)
506ba597cAnurag S. Maskey		return;
516ba597cAnurag S. Maskey
526ba597cAnurag S. Maskey	switch (value->nwv_value_type) {
536ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_BOOLEAN:
546ba597cAnurag S. Maskey		free(value->nwv_values.nwv_boolean);
556ba597cAnurag S. Maskey		break;
566ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_INT64:
576ba597cAnurag S. Maskey		free(value->nwv_values.nwv_int64);
586ba597cAnurag S. Maskey		break;
596ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_UINT64:
606ba597cAnurag S. Maskey		free(value->nwv_values.nwv_uint64);
616ba597cAnurag S. Maskey		break;
626ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_STRING:
636ba597cAnurag S. Maskey		for (i = 0; i < value->nwv_value_numvalues; i++)
646ba597cAnurag S. Maskey			free(value->nwv_values.nwv_string[i]);
656ba597cAnurag S. Maskey		free(value->nwv_values.nwv_string);
666ba597cAnurag S. Maskey		break;
676ba597cAnurag S. Maskey	}
686ba597cAnurag S. Maskey	free(value);
696ba597cAnurag S. Maskey}
706ba597cAnurag S. Maskey
716ba597cAnurag S. Maskeynwam_error_t
726ba597cAnurag S. Maskeynwam_value_create(nwam_value_type_t value_type, void *values, uint_t numvalues,
736ba597cAnurag S. Maskey    nwam_value_t *valuep)
746ba597cAnurag S. Maskey{
756ba597cAnurag S. Maskey	nwam_value_t newvalue;
766ba597cAnurag S. Maskey	boolean_t *values_boolean;
776ba597cAnurag S. Maskey	int64_t *values_int64;
786ba597cAnurag S. Maskey	uint64_t *values_uint64;
796ba597cAnurag S. Maskey	char **values_string;
806ba597cAnurag S. Maskey	int i, j;
816ba597cAnurag S. Maskey	nwam_error_t err = NWAM_SUCCESS;
826ba597cAnurag S. Maskey
836ba597cAnurag S. Maskey	*valuep = NULL;
846ba597cAnurag S. Maskey
856ba597cAnurag S. Maskey	if ((newvalue = calloc(1, sizeof (struct nwam_value))) == NULL)
866ba597cAnurag S. Maskey		return (NWAM_NO_MEMORY);
876ba597cAnurag S. Maskey
886ba597cAnurag S. Maskey	newvalue->nwv_value_type = value_type;
896ba597cAnurag S. Maskey	newvalue->nwv_value_numvalues = numvalues;
906ba597cAnurag S. Maskey
916ba597cAnurag S. Maskey	switch (value_type) {
926ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_BOOLEAN:
936ba597cAnurag S. Maskey		values_boolean = values;
946ba597cAnurag S. Maskey		if ((newvalue->nwv_values.nwv_boolean =
956ba597cAnurag S. Maskey		    calloc(numvalues, sizeof (boolean_t))) == NULL) {
966ba597cAnurag S. Maskey			free(newvalue);
976ba597cAnurag S. Maskey			return (NWAM_NO_MEMORY);
986ba597cAnurag S. Maskey		}
996ba597cAnurag S. Maskey		for (i = 0; i < numvalues; i++)
1006ba597cAnurag S. Maskey			newvalue->nwv_values.nwv_boolean[i] = values_boolean[i];
1016ba597cAnurag S. Maskey		break;
1026ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_INT64:
1036ba597cAnurag S. Maskey		values_int64 = values;
1046ba597cAnurag S. Maskey		if ((newvalue->nwv_values.nwv_int64 =
1056ba597cAnurag S. Maskey		    calloc(numvalues, sizeof (int64_t))) == NULL) {
1066ba597cAnurag S. Maskey			free(newvalue);
1076ba597cAnurag S. Maskey			return (NWAM_NO_MEMORY);
1086ba597cAnurag S. Maskey		}
1096ba597cAnurag S. Maskey		for (i = 0; i < numvalues; i++)
1106ba597cAnurag S. Maskey			newvalue->nwv_values.nwv_int64[i] = values_int64[i];
1116ba597cAnurag S. Maskey		break;
1126ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_UINT64:
1136ba597cAnurag S. Maskey		values_uint64 = values;
1146ba597cAnurag S. Maskey		if ((newvalue->nwv_values.nwv_uint64 =
1156ba597cAnurag S. Maskey		    calloc(numvalues, sizeof (uint64_t))) == NULL) {
1166ba597cAnurag S. Maskey			free(newvalue);
1176ba597cAnurag S. Maskey			return (NWAM_NO_MEMORY);
1186ba597cAnurag S. Maskey		}
1196ba597cAnurag S. Maskey		for (i = 0; i < numvalues; i++)
1206ba597cAnurag S. Maskey			newvalue->nwv_values.nwv_uint64[i] = values_uint64[i];
1216ba597cAnurag S. Maskey		break;
1226ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_STRING:
1236ba597cAnurag S. Maskey		values_string = values;
1246ba597cAnurag S. Maskey		if ((newvalue->nwv_values.nwv_string =
1256ba597cAnurag S. Maskey		    calloc(numvalues, sizeof (char *))) == NULL) {
1266ba597cAnurag S. Maskey			free(newvalue);
1276ba597cAnurag S. Maskey			return (NWAM_NO_MEMORY);
1286ba597cAnurag S. Maskey		}
1296ba597cAnurag S. Maskey		for (i = 0; i < numvalues; i++) {
1306ba597cAnurag S. Maskey			if (strnlen(values_string[i], NWAM_MAX_VALUE_LEN) ==
1316ba597cAnurag S. Maskey			    NWAM_MAX_VALUE_LEN) {
1326ba597cAnurag S. Maskey				err = NWAM_ENTITY_INVALID_VALUE;
1336ba597cAnurag S. Maskey			} else if ((newvalue->nwv_values.nwv_string[i] =
1346ba597cAnurag S. Maskey			    strdup(values_string[i])) == NULL) {
1356ba597cAnurag S. Maskey				err = NWAM_NO_MEMORY;
1366ba597cAnurag S. Maskey			}
1376ba597cAnurag S. Maskey			if (err != NWAM_SUCCESS) {
1386ba597cAnurag S. Maskey				for (j = 0; j < i; j++)
1396ba597cAnurag S. Maskey					free(
1406ba597cAnurag S. Maskey					    newvalue->nwv_values.nwv_string[i]);
1416ba597cAnurag S. Maskey				free(newvalue->nwv_values.nwv_string);
1426ba597cAnurag S. Maskey				free(newvalue);
1436ba597cAnurag S. Maskey				return (err);
1446ba597cAnurag S. Maskey			}
1456ba597cAnurag S. Maskey		}
1466ba597cAnurag S. Maskey		break;
1476ba597cAnurag S. Maskey	default:
1486ba597cAnurag S. Maskey		break;
1496ba597cAnurag S. Maskey	}
1506ba597cAnurag S. Maskey
1516ba597cAnurag S. Maskey	*valuep = newvalue;
1526ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
1536ba597cAnurag S. Maskey}
1546ba597cAnurag S. Maskey
1556ba597cAnurag S. Maskeynwam_error_t
1566ba597cAnurag S. Maskeynwam_value_copy(nwam_value_t old, nwam_value_t *newp)
1576ba597cAnurag S. Maskey{
1586ba597cAnurag S. Maskey	void *values;
1596ba597cAnurag S. Maskey
1606ba597cAnurag S. Maskey	assert(old != NULL && newp != NULL);
1616ba597cAnurag S. Maskey
1626ba597cAnurag S. Maskey	switch (old->nwv_value_type) {
1636ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_BOOLEAN:
1646ba597cAnurag S. Maskey		values = old->nwv_values.nwv_boolean;
1656ba597cAnurag S. Maskey		break;
1666ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_INT64:
1676ba597cAnurag S. Maskey		values = old->nwv_values.nwv_int64;
1686ba597cAnurag S. Maskey		break;
1696ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_UINT64:
1706ba597cAnurag S. Maskey		values = old->nwv_values.nwv_uint64;
1716ba597cAnurag S. Maskey		break;
1726ba597cAnurag S. Maskey	case NWAM_VALUE_TYPE_STRING:
1736ba597cAnurag S. Maskey		values = old->nwv_values.nwv_string;
1746ba597cAnurag S. Maskey		break;
1756ba597cAnurag S. Maskey	default:
1766ba597cAnurag S. Maskey		return (NWAM_INVALID_ARG);
1776ba597cAnurag S. Maskey	}
1786ba597cAnurag S. Maskey	return (nwam_value_create(old->nwv_value_type, values,
1796ba597cAnurag S. Maskey	    old->nwv_value_numvalues, newp));
1806ba597cAnurag S. Maskey}
1816ba597cAnurag S. Maskeynwam_error_t
1826ba597cAnurag S. Maskeynwam_value_create_boolean_array(boolean_t *values, uint_t numvalues,
1836ba597cAnurag S. Maskey    nwam_value_t *valuep)
1846ba597cAnurag S. Maskey{
1856ba597cAnurag S. Maskey	return (nwam_value_create(NWAM_VALUE_TYPE_BOOLEAN, values, numvalues,
1866ba597cAnurag S. Maskey	    valuep));
1876ba597cAnurag S. Maskey}
1886ba597cAnurag S. Maskey
1896ba597cAnurag S. Maskeynwam_error_t
1906ba597cAnurag S. Maskeynwam_value_create_boolean(boolean_t value, nwam_value_t *valuep)
1916ba597cAnurag S. Maskey{
1926ba597cAnurag S. Maskey	return (nwam_value_create_boolean_array(&value, 1, valuep));
1936ba597cAnurag S. Maskey}
1946ba597cAnurag S. Maskey
1956ba597cAnurag S. Maskeynwam_error_t
1966ba597cAnurag S. Maskeynwam_value_create_int64_array(int64_t *values, uint_t numvalues,
1976ba597cAnurag S. Maskey    nwam_value_t *valuep)
1986ba597cAnurag S. Maskey{
1996ba597cAnurag S. Maskey	return (nwam_value_create(NWAM_VALUE_TYPE_INT64, values, numvalues,
2006ba597cAnurag S. Maskey	    valuep));
2016ba597cAnurag S. Maskey}
2026ba597cAnurag S. Maskey
2036ba597cAnurag S. Maskeynwam_error_t
2046ba597cAnurag S. Maskeynwam_value_create_int64(int64_t value, nwam_value_t *valuep)
2056ba597cAnurag S. Maskey{
2066ba597cAnurag S. Maskey	return (nwam_value_create_int64_array(&value, 1, valuep));
2076ba597cAnurag S. Maskey}
2086ba597cAnurag S. Maskey
2096ba597cAnurag S. Maskeynwam_error_t
2106ba597cAnurag S. Maskeynwam_value_create_uint64_array(uint64_t *values, uint_t numvalues,
2116ba597cAnurag S. Maskey    nwam_value_t *valuep)
2126ba597cAnurag S. Maskey{
2136ba597cAnurag S. Maskey	return (nwam_value_create(NWAM_VALUE_TYPE_UINT64, values, numvalues,
2146ba597cAnurag S. Maskey	    valuep));
2156ba597cAnurag S. Maskey}
2166ba597cAnurag S. Maskey
2176ba597cAnurag S. Maskeynwam_error_t
2186ba597cAnurag S. Maskeynwam_value_create_uint64(uint64_t value, nwam_value_t *valuep)
2196ba597cAnurag S. Maskey{
2206ba597cAnurag S. Maskey	return (nwam_value_create_uint64_array(&value, 1, valuep));
2216ba597cAnurag S. Maskey}
2226ba597cAnurag S. Maskey
2236ba597cAnurag S. Maskeynwam_error_t
2246ba597cAnurag S. Maskeynwam_value_create_string_array(char **values, uint_t numvalues,
2256ba597cAnurag S. Maskey    nwam_value_t *valuep)
2266ba597cAnurag S. Maskey{
2276ba597cAnurag S. Maskey	return (nwam_value_create(NWAM_VALUE_TYPE_STRING, values, numvalues,
2286ba597cAnurag S. Maskey	    valuep));
2296ba597cAnurag S. Maskey}
2306ba597cAnurag S. Maskey
2316ba597cAnurag S. Maskeynwam_error_t
2326ba597cAnurag S. Maskeynwam_value_create_string(char *value, nwam_value_t *valuep)
2336ba597cAnurag S. Maskey{
2346ba597cAnurag S. Maskey	return (nwam_value_create_string_array(&value, 1, valuep));
2356ba597cAnurag S. Maskey}
2366ba597cAnurag S. Maskey
2376ba597cAnurag S. Maskeynwam_error_t
2386ba597cAnurag S. Maskeynwam_value_get_boolean_array(nwam_value_t value, boolean_t **valuesp,
2396ba597cAnurag S. Maskey    uint_t *numvaluesp)
2406ba597cAnurag S. Maskey{
2416ba597cAnurag S. Maskey	assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
2426ba597cAnurag S. Maskey
2436ba597cAnurag S. Maskey	*numvaluesp = value->nwv_value_numvalues;
2446ba597cAnurag S. Maskey	*valuesp = value->nwv_values.nwv_boolean;
2456ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
2466ba597cAnurag S. Maskey}
2476ba597cAnurag S. Maskey
2486ba597cAnurag S. Maskeynwam_error_t
2496ba597cAnurag S. Maskeynwam_value_get_boolean(nwam_value_t value, boolean_t *valuep)
2506ba597cAnurag S. Maskey{
2516ba597cAnurag S. Maskey	uint_t numvalues;
2526ba597cAnurag S. Maskey	boolean_t *myvaluesp;
2536ba597cAnurag S. Maskey	nwam_error_t err;
2546ba597cAnurag S. Maskey
2556ba597cAnurag S. Maskey	err = nwam_value_get_boolean_array(value, &myvaluesp, &numvalues);
2566ba597cAnurag S. Maskey	if (err != NWAM_SUCCESS)
2576ba597cAnurag S. Maskey		return (err);
2586ba597cAnurag S. Maskey	if (numvalues != 1)
2596ba597cAnurag S. Maskey		return (NWAM_ENTITY_MULTIPLE_VALUES);
2606ba597cAnurag S. Maskey
2616ba597cAnurag S. Maskey	*valuep = myvaluesp[0];
2626ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
2636ba597cAnurag S. Maskey}
2646ba597cAnurag S. Maskey
2656ba597cAnurag S. Maskeynwam_error_t
2666ba597cAnurag S. Maskeynwam_value_get_int64_array(nwam_value_t value, int64_t **valuesp,
2676ba597cAnurag S. Maskey    uint_t *numvaluesp)
2686ba597cAnurag S. Maskey{
2696ba597cAnurag S. Maskey	assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
2706ba597cAnurag S. Maskey
2716ba597cAnurag S. Maskey	*numvaluesp = value->nwv_value_numvalues;
2726ba597cAnurag S. Maskey	*valuesp = value->nwv_values.nwv_int64;
2736ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
2746ba597cAnurag S. Maskey}
2756ba597cAnurag S. Maskey
2766ba597cAnurag S. Maskeynwam_error_t
2776ba597cAnurag S. Maskeynwam_value_get_int64(nwam_value_t value, int64_t *valuep)
2786ba597cAnurag S. Maskey{
2796ba597cAnurag S. Maskey	uint_t numvalues;
2806ba597cAnurag S. Maskey	int64_t *myvaluesp;
2816ba597cAnurag S. Maskey	nwam_error_t err;
2826ba597cAnurag S. Maskey
2836ba597cAnurag S. Maskey	err = nwam_value_get_int64_array(value, &myvaluesp, &numvalues);
2846ba597cAnurag S. Maskey	if (err != NWAM_SUCCESS)
2856ba597cAnurag S. Maskey		return (err);
2866ba597cAnurag S. Maskey	if (numvalues != 1)
2876ba597cAnurag S. Maskey		return (NWAM_ENTITY_MULTIPLE_VALUES);
2886ba597cAnurag S. Maskey
2896ba597cAnurag S. Maskey	*valuep = myvaluesp[0];
2906ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
2916ba597cAnurag S. Maskey}
2926ba597cAnurag S. Maskey
2936ba597cAnurag S. Maskeynwam_error_t
2946ba597cAnurag S. Maskeynwam_value_get_uint64_array(nwam_value_t value, uint64_t **valuesp,
2956ba597cAnurag S. Maskey    uint_t *numvaluesp)
2966ba597cAnurag S. Maskey{
2976ba597cAnurag S. Maskey	assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
2986ba597cAnurag S. Maskey
2996ba597cAnurag S. Maskey	*numvaluesp = value->nwv_value_numvalues;
3006ba597cAnurag S. Maskey	*valuesp = value->nwv_values.nwv_uint64;
3016ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
3026ba597cAnurag S. Maskey}
3036ba597cAnurag S. Maskey
3046ba597cAnurag S. Maskeynwam_error_t
3056ba597cAnurag S. Maskeynwam_value_get_uint64(nwam_value_t value, uint64_t *valuep)
3066ba597cAnurag S. Maskey{
3076ba597cAnurag S. Maskey	uint_t numvalues;
3086ba597cAnurag S. Maskey	uint64_t *myvaluesp;
3096ba597cAnurag S. Maskey	nwam_error_t err;
3106ba597cAnurag S. Maskey
3116ba597cAnurag S. Maskey	err = nwam_value_get_uint64_array(value, &myvaluesp, &numvalues);
3126ba597cAnurag S. Maskey	if (err != NWAM_SUCCESS)
3136ba597cAnurag S. Maskey		return (err);
3146ba597cAnurag S. Maskey	if (numvalues != 1)
3156ba597cAnurag S. Maskey		return (NWAM_ENTITY_MULTIPLE_VALUES);
3166ba597cAnurag S. Maskey
3176ba597cAnurag S. Maskey	*valuep = myvaluesp[0];
3186ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
3196ba597cAnurag S. Maskey}
3206ba597cAnurag S. Maskey
3216ba597cAnurag S. Maskeynwam_error_t
3226ba597cAnurag S. Maskeynwam_value_get_string_array(nwam_value_t value, char ***valuesp,
3236ba597cAnurag S. Maskey    uint_t *numvaluesp)
3246ba597cAnurag S. Maskey{
3256ba597cAnurag S. Maskey	assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
3266ba597cAnurag S. Maskey
3276ba597cAnurag S. Maskey	*numvaluesp = value->nwv_value_numvalues;
3286ba597cAnurag S. Maskey	*valuesp = value->nwv_values.nwv_string;
3296ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
3306ba597cAnurag S. Maskey}
3316ba597cAnurag S. Maskey
3326ba597cAnurag S. Maskeynwam_error_t
3336ba597cAnurag S. Maskeynwam_value_get_string(nwam_value_t value, char **valuep)
3346ba597cAnurag S. Maskey{
3356ba597cAnurag S. Maskey	uint_t numvalues;
3366ba597cAnurag S. Maskey	char **myvaluesp;
3376ba597cAnurag S. Maskey	nwam_error_t err;
3386ba597cAnurag S. Maskey
3396ba597cAnurag S. Maskey	err = nwam_value_get_string_array(value, &myvaluesp, &numvalues);
3406ba597cAnurag S. Maskey	if (err != NWAM_SUCCESS)
3416ba597cAnurag S. Maskey		return (err);
3426ba597cAnurag S. Maskey	if (numvalues != 1)
3436ba597cAnurag S. Maskey		return (NWAM_ENTITY_MULTIPLE_VALUES);
3446ba597cAnurag S. Maskey
3456ba597cAnurag S. Maskey	*valuep = myvaluesp[0];
3466ba597cAnurag S. Maskey	return (NWAM_SUCCESS);
3476ba597cAnurag S. Maskey}
348