wscutil: Move DeviceType parsing from p2p & eap-wsc to a function

Move the WSC Primary Device Type parsing from p2p.c and eap-wsc.c to a
common function in wscutil.c supporting both formats so that it can be
used in ap.c too.
This commit is contained in:
Andrew Zaborowski 2021-04-26 15:26:35 +02:00 committed by Denis Kenzior
parent 0ad463742b
commit 8d58f5b679
4 changed files with 54 additions and 45 deletions

View File

@ -1742,19 +1742,12 @@ static bool load_primary_device_type(struct l_settings *settings,
struct wsc_primary_device_type *pdt)
{
const char *v;
int r;
v = l_settings_get_value(settings, "WSC", "PrimaryDeviceType");
if (!v)
return false;
r = sscanf(v, "%hx-%2hhx%2hhx%2hhx%2hhx-%2hx", &pdt->category,
&pdt->oui[0], &pdt->oui[1], &pdt->oui[2],
&pdt->oui_type, &pdt->subcategory);
if (r != 6)
return false;
return true;
return wsc_device_type_from_setting_str(v, pdt);
}
static bool load_constrained_string(struct l_settings *settings,

View File

@ -4355,43 +4355,12 @@ struct p2p_device *p2p_device_update_from_genl(struct l_genl_msg *msg,
str = l_settings_get_string(iwd_get_config(), "P2P", "DeviceType");
/*
* Standard WSC subcategories are unique and more specific than
* categories so there's no point for the user to specify the
* category if they choose to use the string format.
*
* As an example our default value (Computer - PC) can be
* encoded as either of:
*
* DeviceType=pc
* DeviceType=0x00010050f2040001
*/
if (str && !wsc_device_type_from_subcategory_str(
&dev->device_info.primary_device_type,
str)) {
unsigned long long u;
char *endp;
u = strtoull(str, &endp, 0);
/*
* Accept any custom category, OUI and subcategory values but
* require non-zero category as a sanity check.
*/
if (*endp != '\0' || (u & 0xffff000000000000ll) == 0)
l_error("[P2P].DeviceType must be a subcategory string "
"or a 64-bit integer encoding the full Primary"
" Device Type attribute: "
"<Category>|<OUI>|<OUI Type>|<Subcategory>");
else {
dev->device_info.primary_device_type.category = u >> 48;
dev->device_info.primary_device_type.oui[0] = u >> 40;
dev->device_info.primary_device_type.oui[1] = u >> 32;
dev->device_info.primary_device_type.oui[2] = u >> 24;
dev->device_info.primary_device_type.oui_type = u >> 16;
dev->device_info.primary_device_type.subcategory = u;
}
}
if (str && !wsc_device_type_from_setting_str(str,
&dev->device_info.primary_device_type))
l_error("[P2P].DeviceType must be a subcategory string "
"or a 64-bit integer encoding the full Primary"
" Device Type attribute: "
"<Category>|<OUI>|<OUI Type>|<Subcategory>");
l_free(str);

View File

@ -3050,3 +3050,48 @@ bool wsc_device_type_from_subcategory_str(struct wsc_primary_device_type *out,
return false;
}
bool wsc_device_type_from_setting_str(const char *value,
struct wsc_primary_device_type *out)
{
unsigned long long u;
char *endp;
if (!value)
return false;
/*
* Standard WSC subcategories are unique and more specific than
* categories so there's no point for the user to specify the
* category if they choose to use the string format.
*
* As an example our default value (Computer - PC) can be
* encoded as either of:
*
* DeviceType=pc
* DeviceType=0x00010050f2040001
* DeviceType=1-0050f204-1
*/
if (wsc_device_type_from_subcategory_str(out, value))
true;
u = strtoull(value, &endp, 0);
/*
* Accept any custom category, OUI and subcategory values but require
* non-zero category as a sanity check.
*/
if (*endp == '\0' && (u & 0xffff000000000000ll) != 0) {
out->category = u >> 48;
out->oui[0] = u >> 40;
out->oui[1] = u >> 32;
out->oui[2] = u >> 24;
out->oui_type = u >> 16;
out->subcategory = u;
return true;
}
return sscanf(value, "%hx-%2hhx%2hhx%2hhx%2hhx-%2hx", &out->category,
&out->oui[0], &out->oui[1], &out->oui[2],
&out->oui_type, &out->subcategory) == 6;
}

View File

@ -681,3 +681,5 @@ bool wsc_device_type_to_dbus_str(const struct wsc_primary_device_type *val,
const char **subcategory_str);
bool wsc_device_type_from_subcategory_str(struct wsc_primary_device_type *out,
const char *subcategory_str);
bool wsc_device_type_from_setting_str(const char *value,
struct wsc_primary_device_type *out);