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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 #include <sys/param.h>
30 #include <sys/types.h>
36 #include <libdllink.h>
37 #include <libdlwlan.h>
39 #include "libnwam_impl.h"
40 #include <libnwam_priv.h>
44 * Functions to support creating, modifying and destroying
45 * known WLAN objects. These represent the WiFi connection history,
46 * and are used by nwamd to identify and connect to known WLANs in
50 static nwam_error_t
valid_keyname(nwam_value_t
);
51 static nwam_error_t
valid_keyslot(nwam_value_t
);
52 static nwam_error_t
valid_secmode(nwam_value_t
);
54 struct nwam_prop_table_entry known_wlan_prop_table_entries
[] = {
55 {NWAM_KNOWN_WLAN_PROP_PRIORITY
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
,
56 1, 1, nwam_valid_uint64
,
57 "specifies priority of known WLAN - lower values are prioritized",
58 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
59 {NWAM_KNOWN_WLAN_PROP_BSSIDS
, NWAM_VALUE_TYPE_STRING
, B_FALSE
,
60 0, NWAM_MAX_NUM_VALUES
, nwam_valid_mac_addr
,
61 "specifies BSSID(s) (of the form aa:bb:cc:dd:ee:ff) associated "
63 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
64 {NWAM_KNOWN_WLAN_PROP_KEYNAME
, NWAM_VALUE_TYPE_STRING
, B_FALSE
,
66 "specifies security key name used with known WLAN",
67 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
68 {NWAM_KNOWN_WLAN_PROP_KEYSLOT
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
,
70 "specifies key slot [1-4] for security key used with known WLAN",
71 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
72 {NWAM_KNOWN_WLAN_PROP_SECURITY_MODE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
,
74 "specifies security mode used for known WLAN",
75 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
}
78 #define NWAM_NUM_KNOWN_WLAN_PROPS \
79 (sizeof (known_wlan_prop_table_entries) / \
80 sizeof (*known_wlan_prop_table_entries))
82 struct nwam_prop_table known_wlan_prop_table
=
83 { NWAM_NUM_KNOWN_WLAN_PROPS
, known_wlan_prop_table_entries
};
86 nwam_known_wlan_read(const char *name
, uint64_t flags
,
87 nwam_known_wlan_handle_t
*kwhp
)
89 return (nwam_read(NWAM_OBJECT_TYPE_KNOWN_WLAN
,
90 NWAM_KNOWN_WLAN_CONF_FILE
, name
, flags
, kwhp
));
94 nwam_known_wlan_create(const char *name
, nwam_known_wlan_handle_t
*kwhp
)
97 nwam_value_t priorityval
= NULL
;
99 assert(kwhp
!= NULL
&& name
!= NULL
);
101 if ((err
= nwam_create(NWAM_OBJECT_TYPE_KNOWN_WLAN
,
102 NWAM_KNOWN_WLAN_CONF_FILE
, name
, kwhp
)) != NWAM_SUCCESS
)
106 * Create new object list for known WLAN. The initial priority is
109 if ((err
= nwam_alloc_object_list(&((*kwhp
)->nwh_data
)))
112 if ((err
= nwam_value_create_uint64(0, &priorityval
)) != NWAM_SUCCESS
)
114 err
= nwam_set_prop_value((*kwhp
)->nwh_data
,
115 NWAM_KNOWN_WLAN_PROP_PRIORITY
, priorityval
);
118 nwam_value_free(priorityval
);
119 if (err
!= NWAM_SUCCESS
) {
120 nwam_known_wlan_free(*kwhp
);
127 nwam_known_wlan_get_name(nwam_known_wlan_handle_t kwh
, char **namep
)
129 return (nwam_get_name(kwh
, namep
));
133 nwam_known_wlan_set_name(nwam_known_wlan_handle_t kwh
, const char *name
)
135 return (nwam_set_name(kwh
, name
));
139 nwam_known_wlan_can_set_name(nwam_known_wlan_handle_t kwh
)
141 return (!kwh
->nwh_committed
);
145 * Used to store wlan names/priorities for prioritized walk.
147 struct nwam_wlan_info
{
149 uint64_t wlan_priority
;
150 boolean_t wlan_walked
;
153 struct nwam_wlan_info_list
{
154 struct nwam_wlan_info
**list
;
159 * Used to read in each known WLAN name/priority.
162 get_wlans_cb(nwam_known_wlan_handle_t kwh
, void *data
)
164 struct nwam_wlan_info_list
*wil
= data
;
165 struct nwam_wlan_info
**list
= wil
->list
;
166 struct nwam_wlan_info
**newlist
= NULL
;
168 nwam_value_t priorityval
= NULL
;
169 uint_t num_wlans
= wil
->num_wlans
;
171 /* Reallocate WLAN list and allocate new info list element. */
172 if ((newlist
= reallocarray(list
, ++num_wlans
,
173 sizeof (struct nwam_wlan_info
*))) == NULL
||
174 (newlist
[num_wlans
- 1] = calloc(1,
175 sizeof (struct nwam_wlan_info
))) == NULL
) {
177 return (NWAM_NO_MEMORY
);
180 /* Update list since realloc() may have relocated it */
183 /* Retrieve name/priority */
184 if ((err
= nwam_known_wlan_get_name(kwh
,
185 &((newlist
[num_wlans
- 1])->wlan_name
))) != NWAM_SUCCESS
||
186 (err
= nwam_known_wlan_get_prop_value(kwh
,
187 NWAM_KNOWN_WLAN_PROP_PRIORITY
, &priorityval
)) != NWAM_SUCCESS
||
188 (err
= nwam_value_get_uint64(priorityval
,
189 &((newlist
[num_wlans
- 1])->wlan_priority
))) != NWAM_SUCCESS
) {
190 free(newlist
[num_wlans
- 1]->wlan_name
);
191 nwam_value_free(priorityval
);
192 free(newlist
[num_wlans
- 1]);
195 nwam_value_free(priorityval
);
197 (newlist
[num_wlans
- 1])->wlan_walked
= B_FALSE
;
199 wil
->num_wlans
= num_wlans
;
201 return (NWAM_SUCCESS
);
205 * Some recursion is required here, since if _WALK_PRIORITY_ORDER is specified,
206 * we need to first walk the list of known WLANs to retrieve names
207 * and priorities, then utilize that list to carry out an in-order walk.
210 nwam_walk_known_wlans(int(*cb
)(nwam_known_wlan_handle_t
, void *), void *data
,
211 uint64_t flags
, int *retp
)
213 nwam_known_wlan_handle_t kwh
;
219 if ((err
= nwam_valid_flags(flags
,
220 NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER
| NWAM_FLAG_BLOCKING
))
224 if ((flags
& NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER
) != 0) {
225 struct nwam_wlan_info_list wil
= { NULL
, 0};
226 uint64_t iflags
= flags
&~
227 NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER
;
228 uint64_t minpriority
;
229 int errval
, i
, j
, minindex
;
231 if (nwam_walk_known_wlans(get_wlans_cb
, &wil
, iflags
, &errval
)
233 err
= (nwam_error_t
)errval
;
239 for (i
= 0; i
< wil
.num_wlans
; i
++) {
240 /* Find lowest priority value not walked so far. */
241 minpriority
= (uint64_t)-1;
242 for (j
= 0; j
< wil
.num_wlans
; j
++) {
243 if (wil
.list
[j
]->wlan_priority
< minpriority
&&
244 !(wil
.list
[j
]->wlan_walked
)) {
246 wil
.list
[j
]->wlan_priority
;
250 wil
.list
[minindex
]->wlan_walked
= B_TRUE
;
251 if ((err
= nwam_known_wlan_read
252 (wil
.list
[minindex
]->wlan_name
,
253 iflags
, &kwh
)) != NWAM_SUCCESS
) {
258 nwam_known_wlan_free(kwh
);
259 err
= NWAM_WALK_HALTED
;
262 nwam_known_wlan_free(kwh
);
265 if (wil
.list
!= NULL
) {
266 for (j
= 0; j
< wil
.num_wlans
; j
++) {
267 free(wil
.list
[j
]->wlan_name
);
277 return (nwam_walk(NWAM_OBJECT_TYPE_KNOWN_WLAN
,
278 NWAM_KNOWN_WLAN_CONF_FILE
, cb
, data
, flags
, retp
, NULL
));
282 nwam_known_wlan_free(nwam_known_wlan_handle_t kwh
)
288 nwam_known_wlan_copy(nwam_known_wlan_handle_t oldkwh
, const char *newname
,
289 nwam_known_wlan_handle_t
*newkwhp
)
291 return (nwam_copy(NWAM_KNOWN_WLAN_CONF_FILE
, oldkwh
, newname
, newkwhp
));
295 nwam_known_wlan_delete_prop(nwam_known_wlan_handle_t kwh
, const char *propname
)
300 assert(kwh
!= NULL
&& propname
!= NULL
);
303 * Duplicate data, remove property and validate. If validation
304 * fails, revert to data duplicated prior to remove.
306 if ((err
= nwam_dup_object_list(kwh
->nwh_data
, &olddata
))
309 if ((err
= nwam_delete_prop(kwh
->nwh_data
, propname
)) != NWAM_SUCCESS
) {
310 nwam_free_object_list(kwh
->nwh_data
);
311 kwh
->nwh_data
= olddata
;
314 if ((err
= nwam_known_wlan_validate(kwh
, NULL
)) != NWAM_SUCCESS
) {
315 nwam_free_object_list(kwh
->nwh_data
);
316 kwh
->nwh_data
= olddata
;
319 nwam_free_object_list(olddata
);
321 return (NWAM_SUCCESS
);
325 nwam_known_wlan_set_prop_value(nwam_known_wlan_handle_t kwh
,
326 const char *propname
, nwam_value_t value
)
330 assert(kwh
!= NULL
&& propname
!= NULL
&& value
!= NULL
);
332 if ((err
= nwam_known_wlan_validate_prop(kwh
, propname
, value
))
336 return (nwam_set_prop_value(kwh
->nwh_data
, propname
, value
));
340 nwam_known_wlan_get_prop_value(nwam_known_wlan_handle_t kwh
,
341 const char *propname
, nwam_value_t
*valuep
)
343 return (nwam_get_prop_value(kwh
->nwh_data
, propname
, valuep
));
347 nwam_known_wlan_walk_props(nwam_known_wlan_handle_t kwh
,
348 int (*cb
)(const char *, nwam_value_t
, void *),
349 void *data
, uint64_t flags
, int *retp
)
351 return (nwam_walk_props(kwh
, cb
, data
, flags
, retp
));
354 struct priority_collision_data
{
360 avoid_priority_collisions_cb(nwam_known_wlan_handle_t kwh
, void *data
)
362 nwam_value_t priorityval
;
364 struct priority_collision_data
*pcd
= data
;
368 err
= nwam_known_wlan_get_name(kwh
, &name
);
369 if (err
!= NWAM_SUCCESS
)
371 if (strcmp(name
, pcd
->wlan_name
) == 0) {
372 /* skip to-be-updated wlan */
374 return (NWAM_SUCCESS
);
378 err
= nwam_known_wlan_get_prop_value(kwh
, NWAM_KNOWN_WLAN_PROP_PRIORITY
,
380 if (err
!= NWAM_SUCCESS
)
382 err
= nwam_value_get_uint64(priorityval
, &priority
);
383 if (err
!= NWAM_SUCCESS
)
385 nwam_value_free(priorityval
);
387 if (priority
< pcd
->priority
)
388 return (NWAM_SUCCESS
);
390 if (priority
== pcd
->priority
) {
391 /* Two priority values collide. Move this one up. */
392 err
= nwam_value_create_uint64(priority
+ 1, &priorityval
);
393 if (err
!= NWAM_SUCCESS
)
395 err
= nwam_known_wlan_set_prop_value(kwh
,
396 NWAM_KNOWN_WLAN_PROP_PRIORITY
, priorityval
);
397 nwam_value_free(priorityval
);
398 if (err
!= NWAM_SUCCESS
) {
402 * We are doing a walk, and will continue shifting until
403 * we find a gap in the priority numbers; thus no need to
404 * do collision checking here.
406 err
= nwam_known_wlan_commit(kwh
,
407 NWAM_FLAG_KNOWN_WLAN_NO_COLLISION_CHECK
);
408 if (err
!= NWAM_SUCCESS
)
412 return (NWAM_SUCCESS
);
416 * Only possiblity left at this point is that we're looking
417 * at a priority greater than the last one we wrote, so we've
418 * found a gap. We can halt the walk now.
420 return (NWAM_WALK_HALTED
);
424 nwam_known_wlan_commit(nwam_known_wlan_handle_t kwh
, uint64_t flags
)
427 nwam_value_t priorityval
;
429 struct priority_collision_data pcd
;
431 assert(kwh
!= NULL
&& kwh
->nwh_data
!= NULL
);
433 if ((err
= nwam_known_wlan_validate(kwh
, NULL
)) != NWAM_SUCCESS
)
437 * If the NO_COLLISION_CHECK flag is set, no need to check for
440 if (flags
& NWAM_FLAG_KNOWN_WLAN_NO_COLLISION_CHECK
)
441 return (nwam_commit(NWAM_KNOWN_WLAN_CONF_FILE
, kwh
,
442 (flags
& NWAM_FLAG_GLOBAL_MASK
) |
443 NWAM_FLAG_ENTITY_KNOWN_WLAN
));
446 * We need to do priority checking. Walk the list, looking
447 * for the first entry with priority greater than or equal
448 * to the entry we're adding. Commit the new one (without
449 * doing additional checking), and then increment other
452 err
= nwam_known_wlan_get_prop_value(kwh
,
453 NWAM_KNOWN_WLAN_PROP_PRIORITY
, &priorityval
);
454 if (err
!= NWAM_SUCCESS
)
456 err
= nwam_value_get_uint64(priorityval
, &(pcd
.priority
));
457 nwam_value_free(priorityval
);
458 if (err
!= NWAM_SUCCESS
)
460 err
= nwam_known_wlan_get_name(kwh
, &(pcd
.wlan_name
));
461 if (err
!= NWAM_SUCCESS
)
463 err
= nwam_walk_known_wlans(avoid_priority_collisions_cb
, &pcd
,
464 NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER
, &ret
);
467 * a halted walk is okay, it just means we didn't have
468 * to walk the entire list to resolve priorities
470 if (ret
!= NWAM_SUCCESS
&& ret
!= NWAM_WALK_HALTED
)
473 return (nwam_known_wlan_commit(kwh
,
474 flags
| NWAM_FLAG_KNOWN_WLAN_NO_COLLISION_CHECK
));
478 nwam_known_wlan_destroy(nwam_known_wlan_handle_t kwh
, uint64_t flags
)
480 return (nwam_destroy(NWAM_KNOWN_WLAN_CONF_FILE
, kwh
,
481 flags
| NWAM_FLAG_ENTITY_KNOWN_WLAN
));
485 nwam_known_wlan_get_prop_description(const char *propname
,
486 const char **descriptionp
)
488 return (nwam_get_prop_description(known_wlan_prop_table
, propname
,
492 /* Property-specific value validation functions should go here. */
495 valid_keyname(nwam_value_t value
)
499 if (nwam_value_get_string(value
, &keyname
) != NWAM_SUCCESS
)
500 return (NWAM_ENTITY_INVALID_VALUE
);
502 if (!dladm_valid_secobj_name(keyname
))
503 return (NWAM_ENTITY_INVALID_VALUE
);
505 return (NWAM_SUCCESS
);
509 valid_keyslot(nwam_value_t value
)
513 if (nwam_value_get_uint64(value
, &keyslot
) != NWAM_SUCCESS
)
514 return (NWAM_ENTITY_INVALID_VALUE
);
516 if (keyslot
< 1 || keyslot
> 4)
517 return (NWAM_ENTITY_INVALID_VALUE
);
519 return (NWAM_SUCCESS
);
523 valid_secmode(nwam_value_t value
)
527 if (nwam_value_get_uint64(value
, &secmode
) != NWAM_SUCCESS
)
528 return (NWAM_ENTITY_INVALID_VALUE
);
530 if (secmode
!= DLADM_WLAN_SECMODE_NONE
&&
531 secmode
!= DLADM_WLAN_SECMODE_WEP
&&
532 secmode
!= DLADM_WLAN_SECMODE_WPA
)
533 return (NWAM_ENTITY_INVALID_VALUE
);
535 return (NWAM_SUCCESS
);
539 nwam_known_wlan_validate(nwam_known_wlan_handle_t kwh
, const char **errpropp
)
541 return (nwam_validate(known_wlan_prop_table
, kwh
, errpropp
));
545 nwam_known_wlan_validate_prop(nwam_known_wlan_handle_t kwh
,
546 const char *propname
, nwam_value_t value
)
548 return (nwam_validate_prop(known_wlan_prop_table
, kwh
, propname
,
553 * Given a property, return expected property data type
556 nwam_known_wlan_get_prop_type(const char *propname
, nwam_value_type_t
*typep
)
558 return (nwam_get_prop_type(known_wlan_prop_table
, propname
, typep
));
562 nwam_known_wlan_prop_multivalued(const char *propname
, boolean_t
*multip
)
564 return (nwam_prop_multivalued(known_wlan_prop_table
, propname
, multip
));
568 nwam_known_wlan_get_default_proplist(const char ***prop_list
,
571 return (nwam_get_default_proplist(known_wlan_prop_table
,
572 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
, prop_list
, numvaluesp
));
576 * Add the given ESSID, BSSID, secmode, keyslot and key name to known WLANs.
577 * BSSID and keyname can be NULL.
580 nwam_known_wlan_add_to_known_wlans(const char *essid
, const char *bssid
,
581 uint32_t secmode
, uint_t keyslot
, const char *keyname
)
583 nwam_known_wlan_handle_t kwh
;
584 nwam_value_t keynameval
= NULL
, keyslotval
= NULL
, bssidsval
= NULL
;
585 nwam_value_t secmodeval
= NULL
, priorityval
= NULL
;
586 char **old_bssids
= NULL
, **new_bssids
;
592 * Check if the given ESSID already exists as known WLAN. If so,
593 * add the BSSID to the bssids property. If not, create one with
594 * the given ESSID and add BSSID if given.
596 err
= nwam_known_wlan_read(essid
, 0, &kwh
);
599 case NWAM_ENTITY_NOT_FOUND
:
600 if ((err
= nwam_known_wlan_create(essid
, &kwh
)) != NWAM_SUCCESS
)
602 /* New known WLAN - set priority to 0 */
603 if ((err
= nwam_value_create_uint64(0, &priorityval
))
605 nwam_known_wlan_free(kwh
);
608 err
= nwam_known_wlan_set_prop_value(kwh
,
609 NWAM_KNOWN_WLAN_PROP_PRIORITY
, priorityval
);
610 nwam_value_free(priorityval
);
611 if (err
!= NWAM_SUCCESS
) {
612 nwam_known_wlan_free(kwh
);
615 /* If BSSID is NULL, nothing more to do here. */
618 if ((err
= nwam_value_create_string((char *)bssid
, &bssidsval
))
620 nwam_known_wlan_free(kwh
);
623 /* Set the bssids property */
624 err
= nwam_known_wlan_set_prop_value(kwh
,
625 NWAM_KNOWN_WLAN_PROP_BSSIDS
, bssidsval
);
626 nwam_value_free(bssidsval
);
627 if (err
!= NWAM_SUCCESS
) {
628 nwam_known_wlan_free(kwh
);
633 /* If no bssid is specified, nothing to do */
637 /* known WLAN exists, retrieve the existing bssids property */
638 err
= nwam_known_wlan_get_prop_value(kwh
,
639 NWAM_KNOWN_WLAN_PROP_BSSIDS
, &bssidsval
);
640 if (err
!= NWAM_SUCCESS
&& err
!= NWAM_ENTITY_NOT_FOUND
) {
641 nwam_known_wlan_free(kwh
);
644 if (err
== NWAM_SUCCESS
) {
645 if ((err
= nwam_value_get_string_array(bssidsval
,
646 &old_bssids
, &nelem
)) != NWAM_SUCCESS
) {
647 nwam_value_free(bssidsval
);
648 nwam_known_wlan_free(kwh
);
652 /* Create a new array to append given BSSID */
653 new_bssids
= calloc(nelem
+ 1, sizeof (char *));
654 if (new_bssids
== NULL
) {
655 nwam_value_free(bssidsval
);
656 nwam_known_wlan_free(kwh
);
657 return (NWAM_NO_MEMORY
);
661 * Copy over existing BSSIDs to the new array. Also, check
662 * to make sure that the given BSSID doesn't already exist
663 * in the known WLAN. If so, do abort copying and return
666 for (i
= 0; i
< nelem
; i
++) {
667 if (strcmp(old_bssids
[i
], bssid
) == 0) {
668 /* nothing to do, so free up everything */
669 for (j
= 0; j
< i
; j
++)
672 nwam_value_free(bssidsval
);
675 new_bssids
[i
] = strdup(old_bssids
[i
]);
677 new_bssids
[nelem
] = strdup(bssid
);
678 nwam_value_free(bssidsval
);
680 err
= nwam_value_create_string_array(new_bssids
, nelem
+ 1,
682 for (i
= 0; i
< nelem
+ 1; i
++)
685 if (err
!= NWAM_SUCCESS
) {
686 nwam_known_wlan_free(kwh
);
689 /* Set the bssids property */
690 err
= nwam_known_wlan_set_prop_value(kwh
,
691 NWAM_KNOWN_WLAN_PROP_BSSIDS
, bssidsval
);
692 nwam_value_free(bssidsval
);
693 if (err
!= NWAM_SUCCESS
) {
694 nwam_known_wlan_free(kwh
);
703 /* Set the security mode property */
704 if ((err
= nwam_value_create_uint64(secmode
, &secmodeval
))
706 nwam_known_wlan_free(kwh
);
709 err
= nwam_known_wlan_set_prop_value(kwh
,
710 NWAM_KNOWN_WLAN_PROP_SECURITY_MODE
, secmodeval
);
711 nwam_value_free(secmodeval
);
713 if (err
!= NWAM_SUCCESS
) {
714 nwam_known_wlan_free(kwh
);
718 if (keyname
!= NULL
) {
719 if ((err
= nwam_value_create_string((char *)keyname
,
720 &keynameval
)) != NWAM_SUCCESS
) {
721 nwam_known_wlan_free(kwh
);
724 err
= nwam_known_wlan_set_prop_value(kwh
,
725 NWAM_KNOWN_WLAN_PROP_KEYNAME
, keynameval
);
726 nwam_value_free(keynameval
);
727 if (err
!= NWAM_SUCCESS
) {
728 nwam_known_wlan_free(kwh
);
731 if ((err
= nwam_value_create_uint64(keyslot
,
732 &keyslotval
)) != NWAM_SUCCESS
) {
733 nwam_known_wlan_free(kwh
);
736 err
= nwam_known_wlan_set_prop_value(kwh
,
737 NWAM_KNOWN_WLAN_PROP_KEYSLOT
, keyslotval
);
738 nwam_value_free(keyslotval
);
741 err
= nwam_known_wlan_commit(kwh
, 0);
742 nwam_known_wlan_free(kwh
);
748 * Remove the given BSSID/keyname from the bssids/keyname property for the
752 nwam_known_wlan_remove_from_known_wlans(const char *essid
, const char *bssid
,
755 nwam_known_wlan_handle_t kwh
;
756 nwam_value_t bssidsval
;
757 char **old_bssids
, **new_bssids
;
762 /* Retrieve the existing bssids */
763 if ((err
= nwam_known_wlan_read(essid
, 0, &kwh
)) != NWAM_SUCCESS
)
765 if ((err
= nwam_known_wlan_get_prop_value(kwh
,
766 NWAM_KNOWN_WLAN_PROP_BSSIDS
, &bssidsval
)) != NWAM_SUCCESS
) {
767 nwam_known_wlan_free(kwh
);
770 if ((err
= nwam_value_get_string_array(bssidsval
, &old_bssids
, &nelem
))
772 nwam_value_free(bssidsval
);
773 nwam_known_wlan_free(kwh
);
777 /* Cycle through the BSSIDs array to find the BSSID to remove */
778 for (i
= 0; i
< nelem
; i
++) {
779 if (strcmp(old_bssids
[i
], bssid
) == 0) {
785 /* Given BSSID was not found in the array */
787 nwam_value_free(bssidsval
);
788 nwam_known_wlan_free(kwh
);
789 return (NWAM_INVALID_ARG
);
792 /* If removing the only BSSID entry, remove the bssids property */
794 nwam_value_free(bssidsval
);
795 if ((err
= nwam_known_wlan_delete_prop(kwh
,
796 NWAM_KNOWN_WLAN_PROP_BSSIDS
)) != NWAM_SUCCESS
) {
797 nwam_known_wlan_free(kwh
);
800 err
= nwam_known_wlan_commit(kwh
, 0);
801 nwam_known_wlan_free(kwh
);
805 new_bssids
= calloc(nelem
- 1, sizeof (char *));
806 if (new_bssids
== NULL
) {
807 nwam_value_free(bssidsval
);
808 nwam_known_wlan_free(kwh
);
809 return (NWAM_NO_MEMORY
);
812 /* Copy over other BSSIDs */
813 for (i
= 0; i
< found
; i
++)
814 new_bssids
[i
] = strdup(old_bssids
[i
]);
815 for (i
= found
+ 1; i
< nelem
; i
++)
816 new_bssids
[i
-1] = strdup(old_bssids
[i
]);
817 nwam_value_free(bssidsval
);
819 err
= nwam_value_create_string_array(new_bssids
, nelem
- 1, &bssidsval
);
820 for (i
= 0; i
< nelem
- 1; i
++)
823 if (err
!= NWAM_SUCCESS
) {
824 nwam_known_wlan_free(kwh
);
828 /* Set the bssids property */
829 err
= nwam_known_wlan_set_prop_value(kwh
, NWAM_KNOWN_WLAN_PROP_BSSIDS
,
831 nwam_value_free(bssidsval
);
832 if (err
!= NWAM_SUCCESS
) {
833 nwam_known_wlan_free(kwh
);
837 if (keyname
!= NULL
) {
838 if ((err
= nwam_known_wlan_delete_prop(kwh
,
839 NWAM_KNOWN_WLAN_PROP_KEYNAME
)) != NWAM_SUCCESS
) {
840 nwam_known_wlan_free(kwh
);
843 if ((err
= nwam_known_wlan_delete_prop(kwh
,
844 NWAM_KNOWN_WLAN_PROP_KEYSLOT
)) != NWAM_SUCCESS
) {
845 nwam_known_wlan_free(kwh
);
850 err
= nwam_known_wlan_commit(kwh
, 0);
851 nwam_known_wlan_free(kwh
);