4 #include <linux/slab.h>
6 #include "wlp-internal.h"
9 const char *__wlp_assoc_frame
[] = {
10 [WLP_ASSOC_D1
] = "WLP_ASSOC_D1",
11 [WLP_ASSOC_D2
] = "WLP_ASSOC_D2",
12 [WLP_ASSOC_M1
] = "WLP_ASSOC_M1",
13 [WLP_ASSOC_M2
] = "WLP_ASSOC_M2",
14 [WLP_ASSOC_M3
] = "WLP_ASSOC_M3",
15 [WLP_ASSOC_M4
] = "WLP_ASSOC_M4",
16 [WLP_ASSOC_M5
] = "WLP_ASSOC_M5",
17 [WLP_ASSOC_M6
] = "WLP_ASSOC_M6",
18 [WLP_ASSOC_M7
] = "WLP_ASSOC_M7",
19 [WLP_ASSOC_M8
] = "WLP_ASSOC_M8",
20 [WLP_ASSOC_F0
] = "WLP_ASSOC_F0",
21 [WLP_ASSOC_E1
] = "WLP_ASSOC_E1",
22 [WLP_ASSOC_E2
] = "WLP_ASSOC_E2",
23 [WLP_ASSOC_C1
] = "WLP_ASSOC_C1",
24 [WLP_ASSOC_C2
] = "WLP_ASSOC_C2",
25 [WLP_ASSOC_C3
] = "WLP_ASSOC_C3",
26 [WLP_ASSOC_C4
] = "WLP_ASSOC_C4",
29 static const char *wlp_assoc_frame_str(unsigned id
)
31 if (id
>= ARRAY_SIZE(__wlp_assoc_frame
))
32 return "unknown association frame";
33 return __wlp_assoc_frame
[id
];
36 static const char *__wlp_assc_error
[] = {
38 "Authenticator Failure",
39 "Rogue activity suspected",
42 "Registrar not ready",
43 "Invalid WSS selection",
45 "Enrollment session timeout",
46 "Device password invalid",
47 "Unsupported version",
50 "Numeric comparison failure",
51 "Waiting for user input",
54 static const char *wlp_assc_error_str(unsigned id
)
56 if (id
>= ARRAY_SIZE(__wlp_assc_error
))
57 return "unknown WLP association error";
58 return __wlp_assc_error
[id
];
61 static inline void wlp_set_attr_hdr(struct wlp_attr_hdr
*hdr
, unsigned type
,
64 hdr
->type
= cpu_to_le16(type
);
65 hdr
->length
= cpu_to_le16(len
);
69 * Populate fields of a constant sized attribute
71 * @returns: total size of attribute including size of new value
73 * We have two instances of this function (wlp_pset and wlp_set): one takes
74 * the value as a parameter, the other takes a pointer to the value as
75 * parameter. They thus only differ in how the value is assigned to the
78 * We use sizeof(*attr) - sizeof(struct wlp_attr_hdr) instead of
79 * sizeof(type) to be able to use this same code for the structures that
80 * contain 8bit enum values and be able to deal with pointer types.
82 #define wlp_set(type, type_code, name) \
83 static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \
85 wlp_set_attr_hdr(&attr->hdr, type_code, \
86 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \
88 return sizeof(*attr); \
91 #define wlp_pset(type, type_code, name) \
92 static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \
94 wlp_set_attr_hdr(&attr->hdr, type_code, \
95 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \
96 attr->name = *value; \
97 return sizeof(*attr); \
101 * Populate fields of a variable attribute
103 * @returns: total size of attribute including size of new value
105 * Provided with a pointer to the memory area reserved for the
106 * attribute structure, the field is populated with the value. The
107 * reserved memory has to contain enough space for the value.
109 #define wlp_vset(type, type_code, name) \
110 static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value, \
113 wlp_set_attr_hdr(&attr->hdr, type_code, len); \
114 memcpy(attr->name, value, len); \
115 return sizeof(*attr) + len; \
118 wlp_vset(char *, WLP_ATTR_DEV_NAME
, dev_name
)
119 wlp_vset(char *, WLP_ATTR_MANUF
, manufacturer
)
120 wlp_set(enum wlp_assoc_type
, WLP_ATTR_MSG_TYPE
, msg_type
)
121 wlp_vset(char *, WLP_ATTR_MODEL_NAME
, model_name
)
122 wlp_vset(char *, WLP_ATTR_MODEL_NR
, model_nr
)
123 wlp_vset(char *, WLP_ATTR_SERIAL
, serial
)
124 wlp_vset(char *, WLP_ATTR_WSS_NAME
, wss_name
)
125 wlp_pset(struct wlp_uuid
*, WLP_ATTR_UUID_E
, uuid_e
)
126 wlp_pset(struct wlp_uuid
*, WLP_ATTR_UUID_R
, uuid_r
)
127 wlp_pset(struct wlp_uuid
*, WLP_ATTR_WSSID
, wssid
)
128 wlp_pset(struct wlp_dev_type
*, WLP_ATTR_PRI_DEV_TYPE
, prim_dev_type
)
129 /*wlp_pset(struct wlp_dev_type *, WLP_ATTR_SEC_DEV_TYPE, sec_dev_type)*/
130 wlp_set(u8
, WLP_ATTR_WLP_VER
, version
)
131 wlp_set(enum wlp_assc_error
, WLP_ATTR_WLP_ASSC_ERR
, wlp_assc_err
)
132 wlp_set(enum wlp_wss_sel_mthd
, WLP_ATTR_WSS_SEL_MTHD
, wss_sel_mthd
)
133 wlp_set(u8
, WLP_ATTR_ACC_ENRL
, accept_enrl
)
134 wlp_set(u8
, WLP_ATTR_WSS_SEC_STAT
, wss_sec_status
)
135 wlp_pset(struct uwb_mac_addr
*, WLP_ATTR_WSS_BCAST
, wss_bcast
)
136 wlp_pset(struct wlp_nonce
*, WLP_ATTR_ENRL_NONCE
, enonce
)
137 wlp_pset(struct wlp_nonce
*, WLP_ATTR_REG_NONCE
, rnonce
)
138 wlp_set(u8
, WLP_ATTR_WSS_TAG
, wss_tag
)
139 wlp_pset(struct uwb_mac_addr
*, WLP_ATTR_WSS_VIRT
, wss_virt
)
142 * Fill in the WSS information attributes
144 * We currently only support one WSS, and this is assumed in this function
145 * that can populate only one WSS information attribute.
147 static size_t wlp_set_wss_info(struct wlp_attr_wss_info
*attr
,
151 void *ptr
= attr
->wss_info
;
152 size_t used
= sizeof(*attr
);
154 datalen
= sizeof(struct wlp_wss_info
) + strlen(wss
->name
);
155 wlp_set_attr_hdr(&attr
->hdr
, WLP_ATTR_WSS_INFO
, datalen
);
156 used
= wlp_set_wssid(ptr
, &wss
->wssid
);
157 used
+= wlp_set_wss_name(ptr
+ used
, wss
->name
, strlen(wss
->name
));
158 used
+= wlp_set_accept_enrl(ptr
+ used
, wss
->accept_enroll
);
159 used
+= wlp_set_wss_sec_status(ptr
+ used
, wss
->secure_status
);
160 used
+= wlp_set_wss_bcast(ptr
+ used
, &wss
->bcast
);
161 return sizeof(*attr
) + used
;
165 * Verify attribute header
167 * @hdr: Pointer to attribute header that will be verified.
168 * @type: Expected attribute type.
169 * @len: Expected length of attribute value (excluding header).
171 * Most attribute values have a known length even when they do have a
172 * length field. This knowledge can be used via this function to verify
173 * that the length field matches the expected value.
175 static int wlp_check_attr_hdr(struct wlp
*wlp
, struct wlp_attr_hdr
*hdr
,
176 enum wlp_attr_type type
, unsigned len
)
178 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
180 if (le16_to_cpu(hdr
->type
) != type
) {
181 dev_err(dev
, "WLP: unexpected header type. Expected "
182 "%u, got %u.\n", type
, le16_to_cpu(hdr
->type
));
185 if (le16_to_cpu(hdr
->length
) != len
) {
186 dev_err(dev
, "WLP: unexpected length in header. Expected "
187 "%u, got %u.\n", len
, le16_to_cpu(hdr
->length
));
194 * Check if header of WSS information attribute valid
196 * @returns: length of WSS attributes (value of length attribute field) if
197 * valid WSS information attribute found
198 * -ENODATA if no WSS information attribute found
199 * -EIO other error occured
201 * The WSS information attribute is optional. The function will be provided
202 * with a pointer to data that could _potentially_ be a WSS information
203 * attribute. If a valid WSS information attribute is found it will return
204 * 0, if no WSS information attribute is found it will return -ENODATA, and
205 * another error will be returned if it is a WSS information attribute, but
206 * some parsing failure occured.
208 static int wlp_check_wss_info_attr_hdr(struct wlp
*wlp
,
209 struct wlp_attr_hdr
*hdr
, size_t buflen
)
211 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
215 if (buflen
< sizeof(*hdr
)) {
216 dev_err(dev
, "WLP: Not enough space in buffer to parse"
217 " WSS information attribute header.\n");
221 if (le16_to_cpu(hdr
->type
) != WLP_ATTR_WSS_INFO
) {
222 /* WSS information is optional */
226 len
= le16_to_cpu(hdr
->length
);
227 if (buflen
< sizeof(*hdr
) + len
) {
228 dev_err(dev
, "WLP: Not enough space in buffer to parse "
229 "variable data. Got %d, expected %d.\n",
230 (int)buflen
, (int)(sizeof(*hdr
) + len
));
240 static ssize_t
wlp_get_attribute(struct wlp
*wlp
, u16 type_code
,
241 struct wlp_attr_hdr
*attr_hdr
, void *value
, ssize_t value_len
,
244 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
245 ssize_t attr_len
= sizeof(*attr_hdr
) + value_len
;
248 if (buflen
< attr_len
) {
249 dev_err(dev
, "WLP: Not enough space in buffer to parse"
250 " attribute field. Need %d, received %zu\n",
251 (int)attr_len
, buflen
);
254 if (wlp_check_attr_hdr(wlp
, attr_hdr
, type_code
, value_len
) < 0) {
255 dev_err(dev
, "WLP: Header verification failed. \n");
258 memcpy(value
, (void *)attr_hdr
+ sizeof(*attr_hdr
), value_len
);
262 static ssize_t
wlp_vget_attribute(struct wlp
*wlp
, u16 type_code
,
263 struct wlp_attr_hdr
*attr_hdr
, void *value
, ssize_t max_value_len
,
266 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
270 if (buflen
< sizeof(*attr_hdr
)) {
271 dev_err(dev
, "WLP: Not enough space in buffer to parse"
275 if (le16_to_cpu(attr_hdr
->type
) != type_code
) {
276 dev_err(dev
, "WLP: Unexpected attribute type. Got %u, "
277 "expected %u.\n", le16_to_cpu(attr_hdr
->type
),
281 len
= le16_to_cpu(attr_hdr
->length
);
282 if (len
> max_value_len
) {
283 dev_err(dev
, "WLP: Attribute larger than maximum "
284 "allowed. Received %zu, max is %d.\n", len
,
288 if (buflen
< sizeof(*attr_hdr
) + len
) {
289 dev_err(dev
, "WLP: Not enough space in buffer to parse "
293 memcpy(value
, (void *)attr_hdr
+ sizeof(*attr_hdr
), len
);
294 return sizeof(*attr_hdr
) + len
;
298 * Get value of attribute from fixed size attribute field.
300 * @attr: Pointer to attribute field.
301 * @value: Pointer to variable in which attribute value will be placed.
302 * @buflen: Size of buffer in which attribute field (including header)
304 * @returns: Amount of given buffer consumed by parsing for this attribute.
306 * The size and type of the value is known by the type of the attribute.
308 #define wlp_get(type, type_code, name) \
309 ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \
310 type *value, ssize_t buflen) \
312 return wlp_get_attribute(wlp, (type_code), &attr->hdr, \
313 value, sizeof(*value), buflen); \
316 #define wlp_get_sparse(type, type_code, name) \
317 static wlp_get(type, type_code, name)
320 * Get value of attribute from variable sized attribute field.
322 * @max: The maximum size of this attribute. This value is dictated by
323 * the maximum value from the WLP specification.
325 * @attr: Pointer to attribute field.
326 * @value: Pointer to variable that will contain the value. The memory
327 * must already have been allocated for this value.
328 * @buflen: Size of buffer in which attribute field (including header)
330 * @returns: Amount of given bufferconsumed by parsing for this attribute.
332 #define wlp_vget(type_val, type_code, name, max) \
333 static ssize_t wlp_get_##name(struct wlp *wlp, \
334 struct wlp_attr_##name *attr, \
335 type_val *value, ssize_t buflen) \
337 return wlp_vget_attribute(wlp, (type_code), &attr->hdr, \
338 value, (max), buflen); \
341 wlp_get(u8
, WLP_ATTR_WLP_VER
, version
)
342 wlp_get_sparse(enum wlp_wss_sel_mthd
, WLP_ATTR_WSS_SEL_MTHD
, wss_sel_mthd
)
343 wlp_get_sparse(struct wlp_dev_type
, WLP_ATTR_PRI_DEV_TYPE
, prim_dev_type
)
344 wlp_get_sparse(enum wlp_assc_error
, WLP_ATTR_WLP_ASSC_ERR
, wlp_assc_err
)
345 wlp_get_sparse(struct wlp_uuid
, WLP_ATTR_UUID_E
, uuid_e
)
346 wlp_get_sparse(struct wlp_uuid
, WLP_ATTR_UUID_R
, uuid_r
)
347 wlp_get(struct wlp_uuid
, WLP_ATTR_WSSID
, wssid
)
348 wlp_get_sparse(u8
, WLP_ATTR_ACC_ENRL
, accept_enrl
)
349 wlp_get_sparse(u8
, WLP_ATTR_WSS_SEC_STAT
, wss_sec_status
)
350 wlp_get_sparse(struct uwb_mac_addr
, WLP_ATTR_WSS_BCAST
, wss_bcast
)
351 wlp_get_sparse(u8
, WLP_ATTR_WSS_TAG
, wss_tag
)
352 wlp_get_sparse(struct uwb_mac_addr
, WLP_ATTR_WSS_VIRT
, wss_virt
)
353 wlp_get_sparse(struct wlp_nonce
, WLP_ATTR_ENRL_NONCE
, enonce
)
354 wlp_get_sparse(struct wlp_nonce
, WLP_ATTR_REG_NONCE
, rnonce
)
356 /* The buffers for the device info attributes can be found in the
357 * wlp_device_info struct. These buffers contain one byte more than the
358 * max allowed by the spec - this is done to be able to add the
359 * terminating \0 for user display. This terminating byte is not required
360 * in the actual attribute field (because it has a length field) so the
361 * maximum allowed for this value is one less than its size in the
364 wlp_vget(char, WLP_ATTR_WSS_NAME
, wss_name
,
365 FIELD_SIZEOF(struct wlp_wss
, name
) - 1)
366 wlp_vget(char, WLP_ATTR_DEV_NAME
, dev_name
,
367 FIELD_SIZEOF(struct wlp_device_info
, name
) - 1)
368 wlp_vget(char, WLP_ATTR_MANUF
, manufacturer
,
369 FIELD_SIZEOF(struct wlp_device_info
, manufacturer
) - 1)
370 wlp_vget(char, WLP_ATTR_MODEL_NAME
, model_name
,
371 FIELD_SIZEOF(struct wlp_device_info
, model_name
) - 1)
372 wlp_vget(char, WLP_ATTR_MODEL_NR
, model_nr
,
373 FIELD_SIZEOF(struct wlp_device_info
, model_nr
) - 1)
374 wlp_vget(char, WLP_ATTR_SERIAL
, serial
,
375 FIELD_SIZEOF(struct wlp_device_info
, serial
) - 1)
378 * Retrieve WSS Name, Accept enroll, Secure status, Broadcast from WSS info
380 * @attr: pointer to WSS name attribute in WSS information attribute field
381 * @info: structure that will be populated with data from WSS information
382 * field (WSS name, Accept enroll, secure status, broadcast address)
383 * @buflen: size of buffer
385 * Although the WSSID attribute forms part of the WSS info attribute it is
386 * retrieved separately and stored in a different location.
388 static ssize_t
wlp_get_wss_info_attrs(struct wlp
*wlp
,
389 struct wlp_attr_hdr
*attr
,
390 struct wlp_wss_tmp_info
*info
,
393 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
396 ssize_t result
= -EINVAL
;
398 result
= wlp_get_wss_name(wlp
, ptr
, info
->name
, buflen
);
400 dev_err(dev
, "WLP: unable to obtain WSS name from "
401 "WSS info in D2 message.\n");
406 result
= wlp_get_accept_enrl(wlp
, ptr
+ used
, &info
->accept_enroll
,
409 dev_err(dev
, "WLP: unable to obtain accepting "
410 "enrollment from WSS info in D2 message.\n");
413 if (info
->accept_enroll
!= 0 && info
->accept_enroll
!= 1) {
414 dev_err(dev
, "WLP: invalid value for accepting "
415 "enrollment in D2 message.\n");
421 result
= wlp_get_wss_sec_status(wlp
, ptr
+ used
, &info
->sec_status
,
424 dev_err(dev
, "WLP: unable to obtain secure "
425 "status from WSS info in D2 message.\n");
428 if (info
->sec_status
!= 0 && info
->sec_status
!= 1) {
429 dev_err(dev
, "WLP: invalid value for secure "
430 "status in D2 message.\n");
436 result
= wlp_get_wss_bcast(wlp
, ptr
+ used
, &info
->bcast
,
439 dev_err(dev
, "WLP: unable to obtain broadcast "
440 "address from WSS info in D2 message.\n");
450 * Create a new WSSID entry for the neighbor, allocate temporary storage
452 * Each neighbor can have many WSS active. We maintain a list of WSSIDs
453 * advertised by neighbor. During discovery we also cache information about
454 * these WSS in temporary storage.
456 * The temporary storage will be removed after it has been used (eg.
457 * displayed to user), the wssid element will be removed from the list when
458 * the neighbor is rediscovered or when it disappears.
460 static struct wlp_wssid_e
*wlp_create_wssid_e(struct wlp
*wlp
,
461 struct wlp_neighbor_e
*neighbor
)
463 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
464 struct wlp_wssid_e
*wssid_e
;
466 wssid_e
= kzalloc(sizeof(*wssid_e
), GFP_KERNEL
);
467 if (wssid_e
== NULL
) {
468 dev_err(dev
, "WLP: unable to allocate memory "
469 "for WSS information.\n");
472 wssid_e
->info
= kzalloc(sizeof(struct wlp_wss_tmp_info
), GFP_KERNEL
);
473 if (wssid_e
->info
== NULL
) {
474 dev_err(dev
, "WLP: unable to allocate memory "
475 "for temporary WSS information.\n");
480 list_add(&wssid_e
->node
, &neighbor
->wssid
);
486 * Parse WSS information attribute
488 * @attr: pointer to WSS information attribute header
489 * @buflen: size of buffer in which WSS information attribute appears
490 * @wssid: will place wssid from WSS info attribute in this location
491 * @wss_info: will place other information from WSS information attribute
494 * memory for @wssid and @wss_info must be allocated when calling this
496 static ssize_t
wlp_get_wss_info(struct wlp
*wlp
, struct wlp_attr_wss_info
*attr
,
497 size_t buflen
, struct wlp_uuid
*wssid
,
498 struct wlp_wss_tmp_info
*wss_info
)
500 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
506 result
= wlp_check_wss_info_attr_hdr(wlp
, (struct wlp_attr_hdr
*)attr
,
511 used
= sizeof(*attr
);
514 result
= wlp_get_wssid(wlp
, ptr
+ used
, wssid
, buflen
- used
);
516 dev_err(dev
, "WLP: unable to obtain WSSID from WSS info.\n");
520 result
= wlp_get_wss_info_attrs(wlp
, ptr
+ used
, wss_info
,
523 dev_err(dev
, "WLP: unable to obtain WSS information "
524 "from WSS information attributes. \n");
528 if (len
+ sizeof(*attr
) != used
) {
529 dev_err(dev
, "WLP: Amount of data parsed does not "
530 "match length field. Parsed %zu, length "
531 "field %zu. \n", used
, len
);
541 * Retrieve WSS info from association frame
543 * @attr: pointer to WSS information attribute
544 * @neighbor: ptr to neighbor being discovered, NULL if enrollment in
546 * @wss: ptr to WSS being enrolled in, NULL if discovery in progress
547 * @buflen: size of buffer in which WSS information appears
549 * The WSS information attribute appears in the D2 association message.
550 * This message is used in two ways: to discover all neighbors or to enroll
551 * into a WSS activated by a neighbor. During discovery we only want to
552 * store the WSS info in a cache, to be deleted right after it has been
553 * used (eg. displayed to the user). During enrollment we store the WSS
554 * information for the lifetime of enrollment.
556 * During discovery we are interested in all WSS information, during
557 * enrollment we are only interested in the WSS being enrolled in. Even so,
558 * when in enrollment we keep parsing the message after finding the WSS of
559 * interest, this simplifies the calling routine in that it can be sure
560 * that all WSS information attributes have been parsed out of the message.
562 * Association frame is process with nbmutex held. The list access is safe.
564 static ssize_t
wlp_get_all_wss_info(struct wlp
*wlp
,
565 struct wlp_attr_wss_info
*attr
,
566 struct wlp_neighbor_e
*neighbor
,
567 struct wlp_wss
*wss
, ssize_t buflen
)
569 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
571 ssize_t result
= -EINVAL
;
572 struct wlp_attr_wss_info
*cur
;
573 struct wlp_uuid wssid
;
574 struct wlp_wss_tmp_info wss_info
;
575 unsigned enroll
; /* 0 - discovery to cache, 1 - enrollment */
576 struct wlp_wssid_e
*wssid_e
;
577 char buf
[WLP_WSS_UUID_STRSIZE
];
582 if (neighbor
!= NULL
&& wss
== NULL
)
583 enroll
= 0; /* discovery */
584 else if (wss
!= NULL
&& neighbor
== NULL
)
585 enroll
= 1; /* enrollment */
590 while (buflen
- used
> 0) {
591 memset(&wss_info
, 0, sizeof(wss_info
));
592 cur
= (void *)cur
+ used
;
593 result
= wlp_get_wss_info(wlp
, cur
, buflen
- used
, &wssid
,
595 if (result
== -ENODATA
) {
598 } else if (result
< 0) {
599 dev_err(dev
, "WLP: Unable to parse WSS information "
600 "from WSS information attribute. \n");
604 if (enroll
&& !memcmp(&wssid
, &wss
->wssid
, sizeof(wssid
))) {
605 if (wss_info
.accept_enroll
!= 1) {
606 dev_err(dev
, "WLP: Requested WSS does "
607 "not accept enrollment.\n");
611 memcpy(wss
->name
, wss_info
.name
, sizeof(wss
->name
));
612 wss
->bcast
= wss_info
.bcast
;
613 wss
->secure_status
= wss_info
.sec_status
;
614 wss
->accept_enroll
= wss_info
.accept_enroll
;
615 wss
->state
= WLP_WSS_STATE_PART_ENROLLED
;
616 wlp_wss_uuid_print(buf
, sizeof(buf
), &wssid
);
617 dev_dbg(dev
, "WLP: Found WSS %s. Enrolling.\n", buf
);
619 wssid_e
= wlp_create_wssid_e(wlp
, neighbor
);
620 if (wssid_e
== NULL
) {
621 dev_err(dev
, "WLP: Cannot create new WSSID "
622 "entry for neighbor %02x:%02x.\n",
623 neighbor
->uwb_dev
->dev_addr
.data
[1],
624 neighbor
->uwb_dev
->dev_addr
.data
[0]);
628 wssid_e
->wssid
= wssid
;
629 *wssid_e
->info
= wss_info
;
635 if (result
< 0 && !enroll
) /* this was a discovery */
636 wlp_remove_neighbor_tmp_info(neighbor
);
643 * Parse WSS information attributes into cache for discovery
645 * @attr: the first WSS information attribute in message
646 * @neighbor: the neighbor whose cache will be populated
647 * @buflen: size of the input buffer
649 static ssize_t
wlp_get_wss_info_to_cache(struct wlp
*wlp
,
650 struct wlp_attr_wss_info
*attr
,
651 struct wlp_neighbor_e
*neighbor
,
654 return wlp_get_all_wss_info(wlp
, attr
, neighbor
, NULL
, buflen
);
658 * Parse WSS information attributes into WSS struct for enrollment
660 * @attr: the first WSS information attribute in message
661 * @wss: the WSS that will be enrolled
662 * @buflen: size of the input buffer
664 static ssize_t
wlp_get_wss_info_to_enroll(struct wlp
*wlp
,
665 struct wlp_attr_wss_info
*attr
,
666 struct wlp_wss
*wss
, ssize_t buflen
)
668 return wlp_get_all_wss_info(wlp
, attr
, NULL
, wss
, buflen
);
672 * Construct a D1 association frame
674 * We use the radio control functions to determine the values of the device
675 * properties. These are of variable length and the total space needed is
676 * tallied first before we start constructing the message. The radio
677 * control functions return strings that are terminated with \0. This
678 * character should not be included in the message (there is a length field
679 * accompanying it in the attribute).
681 static int wlp_build_assoc_d1(struct wlp
*wlp
, struct wlp_wss
*wss
,
682 struct sk_buff
**skb
)
685 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
687 struct wlp_device_info
*info
;
689 struct wlp_frame_assoc
*_d1
;
690 struct sk_buff
*_skb
;
693 if (wlp
->dev_info
== NULL
) {
694 result
= __wlp_setup_device_info(wlp
);
696 dev_err(dev
, "WLP: Unable to setup device "
697 "information for D1 message.\n");
701 info
= wlp
->dev_info
;
702 _skb
= dev_alloc_skb(sizeof(*_d1
)
703 + sizeof(struct wlp_attr_uuid_e
)
704 + sizeof(struct wlp_attr_wss_sel_mthd
)
705 + sizeof(struct wlp_attr_dev_name
)
707 + sizeof(struct wlp_attr_manufacturer
)
708 + strlen(info
->manufacturer
)
709 + sizeof(struct wlp_attr_model_name
)
710 + strlen(info
->model_name
)
711 + sizeof(struct wlp_attr_model_nr
)
712 + strlen(info
->model_nr
)
713 + sizeof(struct wlp_attr_serial
)
714 + strlen(info
->serial
)
715 + sizeof(struct wlp_attr_prim_dev_type
)
716 + sizeof(struct wlp_attr_wlp_assc_err
));
718 dev_err(dev
, "WLP: Cannot allocate memory for association "
723 _d1
= (void *) _skb
->data
;
724 _d1
->hdr
.mux_hdr
= cpu_to_le16(WLP_PROTOCOL_ID
);
725 _d1
->hdr
.type
= WLP_FRAME_ASSOCIATION
;
726 _d1
->type
= WLP_ASSOC_D1
;
728 wlp_set_version(&_d1
->version
, WLP_VERSION
);
729 wlp_set_msg_type(&_d1
->msg_type
, WLP_ASSOC_D1
);
731 used
= wlp_set_uuid_e(d1_itr
, &wlp
->uuid
);
732 used
+= wlp_set_wss_sel_mthd(d1_itr
+ used
, WLP_WSS_REG_SELECT
);
733 used
+= wlp_set_dev_name(d1_itr
+ used
, info
->name
,
735 used
+= wlp_set_manufacturer(d1_itr
+ used
, info
->manufacturer
,
736 strlen(info
->manufacturer
));
737 used
+= wlp_set_model_name(d1_itr
+ used
, info
->model_name
,
738 strlen(info
->model_name
));
739 used
+= wlp_set_model_nr(d1_itr
+ used
, info
->model_nr
,
740 strlen(info
->model_nr
));
741 used
+= wlp_set_serial(d1_itr
+ used
, info
->serial
,
742 strlen(info
->serial
));
743 used
+= wlp_set_prim_dev_type(d1_itr
+ used
, &info
->prim_dev_type
);
744 used
+= wlp_set_wlp_assc_err(d1_itr
+ used
, WLP_ASSOC_ERROR_NONE
);
745 skb_put(_skb
, sizeof(*_d1
) + used
);
752 * Construct a D2 association frame
754 * We use the radio control functions to determine the values of the device
755 * properties. These are of variable length and the total space needed is
756 * tallied first before we start constructing the message. The radio
757 * control functions return strings that are terminated with \0. This
758 * character should not be included in the message (there is a length field
759 * accompanying it in the attribute).
762 int wlp_build_assoc_d2(struct wlp
*wlp
, struct wlp_wss
*wss
,
763 struct sk_buff
**skb
, struct wlp_uuid
*uuid_e
)
766 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
768 struct wlp_device_info
*info
;
770 struct wlp_frame_assoc
*_d2
;
771 struct sk_buff
*_skb
;
775 if (wlp
->dev_info
== NULL
) {
776 result
= __wlp_setup_device_info(wlp
);
778 dev_err(dev
, "WLP: Unable to setup device "
779 "information for D2 message.\n");
783 info
= wlp
->dev_info
;
784 mem_needed
= sizeof(*_d2
)
785 + sizeof(struct wlp_attr_uuid_e
)
786 + sizeof(struct wlp_attr_uuid_r
)
787 + sizeof(struct wlp_attr_dev_name
)
789 + sizeof(struct wlp_attr_manufacturer
)
790 + strlen(info
->manufacturer
)
791 + sizeof(struct wlp_attr_model_name
)
792 + strlen(info
->model_name
)
793 + sizeof(struct wlp_attr_model_nr
)
794 + strlen(info
->model_nr
)
795 + sizeof(struct wlp_attr_serial
)
796 + strlen(info
->serial
)
797 + sizeof(struct wlp_attr_prim_dev_type
)
798 + sizeof(struct wlp_attr_wlp_assc_err
);
799 if (wlp
->wss
.state
>= WLP_WSS_STATE_ACTIVE
)
800 mem_needed
+= sizeof(struct wlp_attr_wss_info
)
801 + sizeof(struct wlp_wss_info
)
802 + strlen(wlp
->wss
.name
);
803 _skb
= dev_alloc_skb(mem_needed
);
805 dev_err(dev
, "WLP: Cannot allocate memory for association "
810 _d2
= (void *) _skb
->data
;
811 _d2
->hdr
.mux_hdr
= cpu_to_le16(WLP_PROTOCOL_ID
);
812 _d2
->hdr
.type
= WLP_FRAME_ASSOCIATION
;
813 _d2
->type
= WLP_ASSOC_D2
;
815 wlp_set_version(&_d2
->version
, WLP_VERSION
);
816 wlp_set_msg_type(&_d2
->msg_type
, WLP_ASSOC_D2
);
818 used
= wlp_set_uuid_e(d2_itr
, uuid_e
);
819 used
+= wlp_set_uuid_r(d2_itr
+ used
, &wlp
->uuid
);
820 if (wlp
->wss
.state
>= WLP_WSS_STATE_ACTIVE
)
821 used
+= wlp_set_wss_info(d2_itr
+ used
, &wlp
->wss
);
822 used
+= wlp_set_dev_name(d2_itr
+ used
, info
->name
,
824 used
+= wlp_set_manufacturer(d2_itr
+ used
, info
->manufacturer
,
825 strlen(info
->manufacturer
));
826 used
+= wlp_set_model_name(d2_itr
+ used
, info
->model_name
,
827 strlen(info
->model_name
));
828 used
+= wlp_set_model_nr(d2_itr
+ used
, info
->model_nr
,
829 strlen(info
->model_nr
));
830 used
+= wlp_set_serial(d2_itr
+ used
, info
->serial
,
831 strlen(info
->serial
));
832 used
+= wlp_set_prim_dev_type(d2_itr
+ used
, &info
->prim_dev_type
);
833 used
+= wlp_set_wlp_assc_err(d2_itr
+ used
, WLP_ASSOC_ERROR_NONE
);
834 skb_put(_skb
, sizeof(*_d2
) + used
);
841 * Allocate memory for and populate fields of F0 association frame
843 * Currently (while focusing on unsecure enrollment) we ignore the
844 * nonce's that could be placed in the message. Only the error field is
845 * populated by the value provided by the caller.
848 int wlp_build_assoc_f0(struct wlp
*wlp
, struct sk_buff
**skb
,
849 enum wlp_assc_error error
)
851 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
852 int result
= -ENOMEM
;
854 struct wlp_frame_assoc f0_hdr
;
855 struct wlp_attr_enonce enonce
;
856 struct wlp_attr_rnonce rnonce
;
857 struct wlp_attr_wlp_assc_err assc_err
;
859 struct sk_buff
*_skb
;
860 struct wlp_nonce tmp
;
862 _skb
= dev_alloc_skb(sizeof(*f0
));
864 dev_err(dev
, "WLP: Unable to allocate memory for F0 "
865 "association frame. \n");
868 f0
= (void *) _skb
->data
;
869 f0
->f0_hdr
.hdr
.mux_hdr
= cpu_to_le16(WLP_PROTOCOL_ID
);
870 f0
->f0_hdr
.hdr
.type
= WLP_FRAME_ASSOCIATION
;
871 f0
->f0_hdr
.type
= WLP_ASSOC_F0
;
872 wlp_set_version(&f0
->f0_hdr
.version
, WLP_VERSION
);
873 wlp_set_msg_type(&f0
->f0_hdr
.msg_type
, WLP_ASSOC_F0
);
874 memset(&tmp
, 0, sizeof(tmp
));
875 wlp_set_enonce(&f0
->enonce
, &tmp
);
876 wlp_set_rnonce(&f0
->rnonce
, &tmp
);
877 wlp_set_wlp_assc_err(&f0
->assc_err
, error
);
878 skb_put(_skb
, sizeof(*f0
));
888 * We just retrieve the values and print it as an error to the user.
889 * Calling function already knows an error occured (F0 indicates error), so
890 * we just parse the content as debug for higher layers.
892 int wlp_parse_f0(struct wlp
*wlp
, struct sk_buff
*skb
)
894 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
895 struct wlp_frame_assoc
*f0
= (void *) skb
->data
;
896 void *ptr
= skb
->data
;
897 size_t len
= skb
->len
;
900 struct wlp_nonce enonce
, rnonce
;
901 enum wlp_assc_error assc_err
;
902 char enonce_buf
[WLP_WSS_NONCE_STRSIZE
];
903 char rnonce_buf
[WLP_WSS_NONCE_STRSIZE
];
906 result
= wlp_get_enonce(wlp
, ptr
+ used
, &enonce
, len
- used
);
908 dev_err(dev
, "WLP: unable to obtain Enrollee nonce "
909 "attribute from F0 message.\n");
913 result
= wlp_get_rnonce(wlp
, ptr
+ used
, &rnonce
, len
- used
);
915 dev_err(dev
, "WLP: unable to obtain Registrar nonce "
916 "attribute from F0 message.\n");
920 result
= wlp_get_wlp_assc_err(wlp
, ptr
+ used
, &assc_err
, len
- used
);
922 dev_err(dev
, "WLP: unable to obtain WLP Association error "
923 "attribute from F0 message.\n");
926 wlp_wss_nonce_print(enonce_buf
, sizeof(enonce_buf
), &enonce
);
927 wlp_wss_nonce_print(rnonce_buf
, sizeof(rnonce_buf
), &rnonce
);
928 dev_err(dev
, "WLP: Received F0 error frame from neighbor. Enrollee "
929 "nonce: %s, Registrar nonce: %s, WLP Association error: %s.\n",
930 enonce_buf
, rnonce_buf
, wlp_assc_error_str(assc_err
));
937 * Retrieve variable device information from association message
939 * The device information parsed is not required in any message. This
940 * routine will thus not fail if an attribute is not present.
941 * The attributes are expected in a certain order, even if all are not
942 * present. The "attribute type" value is used to ensure the attributes
943 * are parsed in the correct order.
945 * If an error is encountered during parsing the function will return an
946 * error code, when this happens the given device_info structure may be
950 int wlp_get_variable_info(struct wlp
*wlp
, void *data
,
951 struct wlp_device_info
*dev_info
, ssize_t len
)
953 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
955 struct wlp_attr_hdr
*hdr
;
959 while (len
- used
> 0) {
960 if (len
- used
< sizeof(*hdr
)) {
961 dev_err(dev
, "WLP: Partial data in frame, cannot "
966 switch (le16_to_cpu(hdr
->type
)) {
968 if (last
>= WLP_ATTR_MANUF
) {
969 dev_err(dev
, "WLP: Incorrect order of "
970 "attribute values in D1 msg.\n");
973 result
= wlp_get_manufacturer(wlp
, data
+ used
,
974 dev_info
->manufacturer
,
977 dev_err(dev
, "WLP: Unable to obtain "
978 "Manufacturer attribute from D1 "
982 last
= WLP_ATTR_MANUF
;
985 case WLP_ATTR_MODEL_NAME
:
986 if (last
>= WLP_ATTR_MODEL_NAME
) {
987 dev_err(dev
, "WLP: Incorrect order of "
988 "attribute values in D1 msg.\n");
991 result
= wlp_get_model_name(wlp
, data
+ used
,
992 dev_info
->model_name
,
995 dev_err(dev
, "WLP: Unable to obtain Model "
996 "name attribute from D1 message.\n");
999 last
= WLP_ATTR_MODEL_NAME
;
1002 case WLP_ATTR_MODEL_NR
:
1003 if (last
>= WLP_ATTR_MODEL_NR
) {
1004 dev_err(dev
, "WLP: Incorrect order of "
1005 "attribute values in D1 msg.\n");
1008 result
= wlp_get_model_nr(wlp
, data
+ used
,
1012 dev_err(dev
, "WLP: Unable to obtain Model "
1013 "number attribute from D1 message.\n");
1016 last
= WLP_ATTR_MODEL_NR
;
1019 case WLP_ATTR_SERIAL
:
1020 if (last
>= WLP_ATTR_SERIAL
) {
1021 dev_err(dev
, "WLP: Incorrect order of "
1022 "attribute values in D1 msg.\n");
1025 result
= wlp_get_serial(wlp
, data
+ used
,
1026 dev_info
->serial
, len
- used
);
1028 dev_err(dev
, "WLP: Unable to obtain Serial "
1029 "number attribute from D1 message.\n");
1032 last
= WLP_ATTR_SERIAL
;
1035 case WLP_ATTR_PRI_DEV_TYPE
:
1036 if (last
>= WLP_ATTR_PRI_DEV_TYPE
) {
1037 dev_err(dev
, "WLP: Incorrect order of "
1038 "attribute values in D1 msg.\n");
1041 result
= wlp_get_prim_dev_type(wlp
, data
+ used
,
1042 &dev_info
->prim_dev_type
,
1045 dev_err(dev
, "WLP: Unable to obtain Primary "
1046 "device type attribute from D1 "
1050 dev_info
->prim_dev_type
.category
=
1051 le16_to_cpu(dev_info
->prim_dev_type
.category
);
1052 dev_info
->prim_dev_type
.subID
=
1053 le16_to_cpu(dev_info
->prim_dev_type
.subID
);
1054 last
= WLP_ATTR_PRI_DEV_TYPE
;
1058 /* This is not variable device information. */
1070 * Parse incoming D1 frame, populate attribute values
1072 * Caller provides pointers to memory already allocated for attributes
1073 * expected in the D1 frame. These variables will be populated.
1076 int wlp_parse_d1_frame(struct wlp
*wlp
, struct sk_buff
*skb
,
1077 struct wlp_uuid
*uuid_e
,
1078 enum wlp_wss_sel_mthd
*sel_mthd
,
1079 struct wlp_device_info
*dev_info
,
1080 enum wlp_assc_error
*assc_err
)
1082 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1083 struct wlp_frame_assoc
*d1
= (void *) skb
->data
;
1084 void *ptr
= skb
->data
;
1085 size_t len
= skb
->len
;
1090 result
= wlp_get_uuid_e(wlp
, ptr
+ used
, uuid_e
, len
- used
);
1092 dev_err(dev
, "WLP: unable to obtain UUID-E attribute from D1 "
1097 result
= wlp_get_wss_sel_mthd(wlp
, ptr
+ used
, sel_mthd
, len
- used
);
1099 dev_err(dev
, "WLP: unable to obtain WSS selection method "
1100 "from D1 message.\n");
1104 result
= wlp_get_dev_name(wlp
, ptr
+ used
, dev_info
->name
,
1107 dev_err(dev
, "WLP: unable to obtain Device Name from D1 "
1112 result
= wlp_get_variable_info(wlp
, ptr
+ used
, dev_info
, len
- used
);
1114 dev_err(dev
, "WLP: unable to obtain Device Information from "
1119 result
= wlp_get_wlp_assc_err(wlp
, ptr
+ used
, assc_err
, len
- used
);
1121 dev_err(dev
, "WLP: unable to obtain WLP Association Error "
1122 "Information from D1 message.\n");
1130 * Handle incoming D1 frame
1132 * The frame has already been verified to contain an Association header with
1133 * the correct version number. Parse the incoming frame, construct and send
1134 * a D2 frame in response.
1136 * It is not clear what to do with most fields in the incoming D1 frame. We
1137 * retrieve and discard the information here for now.
1139 void wlp_handle_d1_frame(struct work_struct
*ws
)
1141 struct wlp_assoc_frame_ctx
*frame_ctx
= container_of(ws
,
1142 struct wlp_assoc_frame_ctx
,
1144 struct wlp
*wlp
= frame_ctx
->wlp
;
1145 struct wlp_wss
*wss
= &wlp
->wss
;
1146 struct sk_buff
*skb
= frame_ctx
->skb
;
1147 struct uwb_dev_addr
*src
= &frame_ctx
->src
;
1149 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1150 struct wlp_uuid uuid_e
;
1151 enum wlp_wss_sel_mthd sel_mthd
= 0;
1152 struct wlp_device_info dev_info
;
1153 enum wlp_assc_error assc_err
;
1154 struct sk_buff
*resp
= NULL
;
1156 /* Parse D1 frame */
1157 mutex_lock(&wss
->mutex
);
1158 mutex_lock(&wlp
->mutex
); /* to access wlp->uuid */
1159 memset(&dev_info
, 0, sizeof(dev_info
));
1160 result
= wlp_parse_d1_frame(wlp
, skb
, &uuid_e
, &sel_mthd
, &dev_info
,
1163 dev_err(dev
, "WLP: Unable to parse incoming D1 frame.\n");
1169 if (!wlp_uuid_is_set(&wlp
->uuid
)) {
1170 dev_err(dev
, "WLP: UUID is not set. Set via sysfs to "
1171 "proceed. Respong to D1 message with error F0.\n");
1172 result
= wlp_build_assoc_f0(wlp
, &resp
,
1173 WLP_ASSOC_ERROR_NOT_READY
);
1175 dev_err(dev
, "WLP: Unable to construct F0 message.\n");
1179 /* Construct D2 frame */
1180 result
= wlp_build_assoc_d2(wlp
, wss
, &resp
, &uuid_e
);
1182 dev_err(dev
, "WLP: Unable to construct D2 message.\n");
1187 BUG_ON(wlp
->xmit_frame
== NULL
);
1188 result
= wlp
->xmit_frame(wlp
, resp
, src
);
1190 dev_err(dev
, "WLP: Unable to transmit D2 association "
1191 "message: %d\n", result
);
1192 if (result
== -ENXIO
)
1193 dev_err(dev
, "WLP: Is network interface up? \n");
1194 /* We could try again ... */
1195 dev_kfree_skb_any(resp
); /* we need to free if tx fails */
1199 mutex_unlock(&wlp
->mutex
);
1200 mutex_unlock(&wss
->mutex
);
1204 * Parse incoming D2 frame, create and populate temporary cache
1206 * @skb: socket buffer in which D2 frame can be found
1207 * @neighbor: the neighbor that sent the D2 frame
1209 * Will allocate memory for temporary storage of information learned during
1212 int wlp_parse_d2_frame_to_cache(struct wlp
*wlp
, struct sk_buff
*skb
,
1213 struct wlp_neighbor_e
*neighbor
)
1215 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1216 struct wlp_frame_assoc
*d2
= (void *) skb
->data
;
1217 void *ptr
= skb
->data
;
1218 size_t len
= skb
->len
;
1221 struct wlp_uuid uuid_e
;
1222 struct wlp_device_info
*nb_info
;
1223 enum wlp_assc_error assc_err
;
1226 result
= wlp_get_uuid_e(wlp
, ptr
+ used
, &uuid_e
, len
- used
);
1228 dev_err(dev
, "WLP: unable to obtain UUID-E attribute from D2 "
1232 if (memcmp(&uuid_e
, &wlp
->uuid
, sizeof(uuid_e
))) {
1233 dev_err(dev
, "WLP: UUID-E in incoming D2 does not match "
1234 "local UUID sent in D1. \n");
1238 result
= wlp_get_uuid_r(wlp
, ptr
+ used
, &neighbor
->uuid
, len
- used
);
1240 dev_err(dev
, "WLP: unable to obtain UUID-R attribute from D2 "
1245 result
= wlp_get_wss_info_to_cache(wlp
, ptr
+ used
, neighbor
,
1248 dev_err(dev
, "WLP: unable to obtain WSS information "
1249 "from D2 message.\n");
1253 neighbor
->info
= kzalloc(sizeof(struct wlp_device_info
), GFP_KERNEL
);
1254 if (neighbor
->info
== NULL
) {
1255 dev_err(dev
, "WLP: cannot allocate memory to store device "
1260 nb_info
= neighbor
->info
;
1261 result
= wlp_get_dev_name(wlp
, ptr
+ used
, nb_info
->name
,
1264 dev_err(dev
, "WLP: unable to obtain Device Name from D2 "
1269 result
= wlp_get_variable_info(wlp
, ptr
+ used
, nb_info
, len
- used
);
1271 dev_err(dev
, "WLP: unable to obtain Device Information from "
1276 result
= wlp_get_wlp_assc_err(wlp
, ptr
+ used
, &assc_err
, len
- used
);
1278 dev_err(dev
, "WLP: unable to obtain WLP Association Error "
1279 "Information from D2 message.\n");
1282 if (assc_err
!= WLP_ASSOC_ERROR_NONE
) {
1283 dev_err(dev
, "WLP: neighbor device returned association "
1284 "error %d\n", assc_err
);
1291 wlp_remove_neighbor_tmp_info(neighbor
);
1296 * Parse incoming D2 frame, populate attribute values of WSS bein enrolled in
1298 * @wss: our WSS that will be enrolled
1299 * @skb: socket buffer in which D2 frame can be found
1300 * @neighbor: the neighbor that sent the D2 frame
1301 * @wssid: the wssid of the WSS in which we want to enroll
1303 * Forms part of enrollment sequence. We are trying to enroll in WSS with
1304 * @wssid by using @neighbor as registrar. A D1 message was sent to
1305 * @neighbor and now we need to parse the D2 response. The neighbor's
1306 * response is searched for the requested WSS and if found (and it accepts
1307 * enrollment), we store the information.
1309 int wlp_parse_d2_frame_to_enroll(struct wlp_wss
*wss
, struct sk_buff
*skb
,
1310 struct wlp_neighbor_e
*neighbor
,
1311 struct wlp_uuid
*wssid
)
1313 struct wlp
*wlp
= container_of(wss
, struct wlp
, wss
);
1314 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1315 void *ptr
= skb
->data
;
1316 size_t len
= skb
->len
;
1319 struct wlp_uuid uuid_e
;
1320 struct wlp_uuid uuid_r
;
1321 struct wlp_device_info nb_info
;
1322 enum wlp_assc_error assc_err
;
1323 char uuid_bufA
[WLP_WSS_UUID_STRSIZE
];
1324 char uuid_bufB
[WLP_WSS_UUID_STRSIZE
];
1326 used
= sizeof(struct wlp_frame_assoc
);
1327 result
= wlp_get_uuid_e(wlp
, ptr
+ used
, &uuid_e
, len
- used
);
1329 dev_err(dev
, "WLP: unable to obtain UUID-E attribute from D2 "
1333 if (memcmp(&uuid_e
, &wlp
->uuid
, sizeof(uuid_e
))) {
1334 dev_err(dev
, "WLP: UUID-E in incoming D2 does not match "
1335 "local UUID sent in D1. \n");
1339 result
= wlp_get_uuid_r(wlp
, ptr
+ used
, &uuid_r
, len
- used
);
1341 dev_err(dev
, "WLP: unable to obtain UUID-R attribute from D2 "
1345 if (memcmp(&uuid_r
, &neighbor
->uuid
, sizeof(uuid_r
))) {
1346 wlp_wss_uuid_print(uuid_bufA
, sizeof(uuid_bufA
),
1348 wlp_wss_uuid_print(uuid_bufB
, sizeof(uuid_bufB
), &uuid_r
);
1349 dev_err(dev
, "WLP: UUID of neighbor does not match UUID "
1350 "learned during discovery. Originally discovered: %s, "
1351 "now from D2 message: %s\n", uuid_bufA
, uuid_bufB
);
1356 wss
->wssid
= *wssid
;
1357 result
= wlp_get_wss_info_to_enroll(wlp
, ptr
+ used
, wss
, len
- used
);
1359 dev_err(dev
, "WLP: unable to obtain WSS information "
1360 "from D2 message.\n");
1363 if (wss
->state
!= WLP_WSS_STATE_PART_ENROLLED
) {
1364 dev_err(dev
, "WLP: D2 message did not contain information "
1365 "for successful enrollment. \n");
1370 /* Place device information on stack to continue parsing of message */
1371 result
= wlp_get_dev_name(wlp
, ptr
+ used
, nb_info
.name
,
1374 dev_err(dev
, "WLP: unable to obtain Device Name from D2 "
1379 result
= wlp_get_variable_info(wlp
, ptr
+ used
, &nb_info
, len
- used
);
1381 dev_err(dev
, "WLP: unable to obtain Device Information from "
1386 result
= wlp_get_wlp_assc_err(wlp
, ptr
+ used
, &assc_err
, len
- used
);
1388 dev_err(dev
, "WLP: unable to obtain WLP Association Error "
1389 "Information from D2 message.\n");
1392 if (assc_err
!= WLP_ASSOC_ERROR_NONE
) {
1393 dev_err(dev
, "WLP: neighbor device returned association "
1394 "error %d\n", assc_err
);
1395 if (wss
->state
== WLP_WSS_STATE_PART_ENROLLED
) {
1396 dev_err(dev
, "WLP: Enrolled in WSS (should not "
1397 "happen according to spec). Undoing. \n");
1409 * Parse C3/C4 frame into provided variables
1411 * @wssid: will point to copy of wssid retrieved from C3/C4 frame
1412 * @tag: will point to copy of tag retrieved from C3/C4 frame
1413 * @virt_addr: will point to copy of virtual address retrieved from C3/C4
1416 * Calling function has to allocate memory for these values.
1418 * skb contains a valid C3/C4 frame, return the individual fields of this
1419 * frame in the provided variables.
1421 int wlp_parse_c3c4_frame(struct wlp
*wlp
, struct sk_buff
*skb
,
1422 struct wlp_uuid
*wssid
, u8
*tag
,
1423 struct uwb_mac_addr
*virt_addr
)
1425 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1427 void *ptr
= skb
->data
;
1428 size_t len
= skb
->len
;
1430 struct wlp_frame_assoc
*assoc
= ptr
;
1432 used
= sizeof(*assoc
);
1433 result
= wlp_get_wssid(wlp
, ptr
+ used
, wssid
, len
- used
);
1435 dev_err(dev
, "WLP: unable to obtain WSSID attribute from "
1436 "%s message.\n", wlp_assoc_frame_str(assoc
->type
));
1440 result
= wlp_get_wss_tag(wlp
, ptr
+ used
, tag
, len
- used
);
1442 dev_err(dev
, "WLP: unable to obtain WSS tag attribute from "
1443 "%s message.\n", wlp_assoc_frame_str(assoc
->type
));
1447 result
= wlp_get_wss_virt(wlp
, ptr
+ used
, virt_addr
, len
- used
);
1449 dev_err(dev
, "WLP: unable to obtain WSS virtual address "
1450 "attribute from %s message.\n",
1451 wlp_assoc_frame_str(assoc
->type
));
1459 * Allocate memory for and populate fields of C1 or C2 association frame
1461 * The C1 and C2 association frames appear identical - except for the type.
1464 int wlp_build_assoc_c1c2(struct wlp
*wlp
, struct wlp_wss
*wss
,
1465 struct sk_buff
**skb
, enum wlp_assoc_type type
)
1467 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1468 int result
= -ENOMEM
;
1470 struct wlp_frame_assoc c_hdr
;
1471 struct wlp_attr_wssid wssid
;
1473 struct sk_buff
*_skb
;
1475 _skb
= dev_alloc_skb(sizeof(*c
));
1477 dev_err(dev
, "WLP: Unable to allocate memory for C1/C2 "
1478 "association frame. \n");
1481 c
= (void *) _skb
->data
;
1482 c
->c_hdr
.hdr
.mux_hdr
= cpu_to_le16(WLP_PROTOCOL_ID
);
1483 c
->c_hdr
.hdr
.type
= WLP_FRAME_ASSOCIATION
;
1484 c
->c_hdr
.type
= type
;
1485 wlp_set_version(&c
->c_hdr
.version
, WLP_VERSION
);
1486 wlp_set_msg_type(&c
->c_hdr
.msg_type
, type
);
1487 wlp_set_wssid(&c
->wssid
, &wss
->wssid
);
1488 skb_put(_skb
, sizeof(*c
));
1497 int wlp_build_assoc_c1(struct wlp
*wlp
, struct wlp_wss
*wss
,
1498 struct sk_buff
**skb
)
1500 return wlp_build_assoc_c1c2(wlp
, wss
, skb
, WLP_ASSOC_C1
);
1504 int wlp_build_assoc_c2(struct wlp
*wlp
, struct wlp_wss
*wss
,
1505 struct sk_buff
**skb
)
1507 return wlp_build_assoc_c1c2(wlp
, wss
, skb
, WLP_ASSOC_C2
);
1512 * Allocate memory for and populate fields of C3 or C4 association frame
1514 * The C3 and C4 association frames appear identical - except for the type.
1517 int wlp_build_assoc_c3c4(struct wlp
*wlp
, struct wlp_wss
*wss
,
1518 struct sk_buff
**skb
, enum wlp_assoc_type type
)
1520 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1521 int result
= -ENOMEM
;
1523 struct wlp_frame_assoc c_hdr
;
1524 struct wlp_attr_wssid wssid
;
1525 struct wlp_attr_wss_tag wss_tag
;
1526 struct wlp_attr_wss_virt wss_virt
;
1528 struct sk_buff
*_skb
;
1530 _skb
= dev_alloc_skb(sizeof(*c
));
1532 dev_err(dev
, "WLP: Unable to allocate memory for C3/C4 "
1533 "association frame. \n");
1536 c
= (void *) _skb
->data
;
1537 c
->c_hdr
.hdr
.mux_hdr
= cpu_to_le16(WLP_PROTOCOL_ID
);
1538 c
->c_hdr
.hdr
.type
= WLP_FRAME_ASSOCIATION
;
1539 c
->c_hdr
.type
= type
;
1540 wlp_set_version(&c
->c_hdr
.version
, WLP_VERSION
);
1541 wlp_set_msg_type(&c
->c_hdr
.msg_type
, type
);
1542 wlp_set_wssid(&c
->wssid
, &wss
->wssid
);
1543 wlp_set_wss_tag(&c
->wss_tag
, wss
->tag
);
1544 wlp_set_wss_virt(&c
->wss_virt
, &wss
->virtual_addr
);
1545 skb_put(_skb
, sizeof(*c
));
1553 int wlp_build_assoc_c3(struct wlp
*wlp
, struct wlp_wss
*wss
,
1554 struct sk_buff
**skb
)
1556 return wlp_build_assoc_c3c4(wlp
, wss
, skb
, WLP_ASSOC_C3
);
1560 int wlp_build_assoc_c4(struct wlp
*wlp
, struct wlp_wss
*wss
,
1561 struct sk_buff
**skb
)
1563 return wlp_build_assoc_c3c4(wlp
, wss
, skb
, WLP_ASSOC_C4
);
1567 #define wlp_send_assoc(type, id) \
1568 static int wlp_send_assoc_##type(struct wlp *wlp, struct wlp_wss *wss, \
1569 struct uwb_dev_addr *dev_addr) \
1571 struct device *dev = &wlp->rc->uwb_dev.dev; \
1573 struct sk_buff *skb = NULL; \
1575 /* Build the frame */ \
1576 result = wlp_build_assoc_##type(wlp, wss, &skb); \
1578 dev_err(dev, "WLP: Unable to construct %s association " \
1579 "frame: %d\n", wlp_assoc_frame_str(id), result);\
1580 goto error_build_assoc; \
1582 /* Send the frame */ \
1583 BUG_ON(wlp->xmit_frame == NULL); \
1584 result = wlp->xmit_frame(wlp, skb, dev_addr); \
1586 dev_err(dev, "WLP: Unable to transmit %s association " \
1587 "message: %d\n", wlp_assoc_frame_str(id), \
1589 if (result == -ENXIO) \
1590 dev_err(dev, "WLP: Is network interface " \
1596 /* We could try again ... */ \
1597 dev_kfree_skb_any(skb);/*we need to free if tx fails*/ \
1598 error_build_assoc: \
1602 wlp_send_assoc(d1
, WLP_ASSOC_D1
)
1603 wlp_send_assoc(c1
, WLP_ASSOC_C1
)
1604 wlp_send_assoc(c3
, WLP_ASSOC_C3
)
1606 int wlp_send_assoc_frame(struct wlp
*wlp
, struct wlp_wss
*wss
,
1607 struct uwb_dev_addr
*dev_addr
,
1608 enum wlp_assoc_type type
)
1611 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1614 result
= wlp_send_assoc_d1(wlp
, wss
, dev_addr
);
1617 result
= wlp_send_assoc_c1(wlp
, wss
, dev_addr
);
1620 result
= wlp_send_assoc_c3(wlp
, wss
, dev_addr
);
1623 dev_err(dev
, "WLP: Received request to send unknown "
1624 "association message.\n");
1632 * Handle incoming C1 frame
1634 * The frame has already been verified to contain an Association header with
1635 * the correct version number. Parse the incoming frame, construct and send
1636 * a C2 frame in response.
1638 void wlp_handle_c1_frame(struct work_struct
*ws
)
1640 struct wlp_assoc_frame_ctx
*frame_ctx
= container_of(ws
,
1641 struct wlp_assoc_frame_ctx
,
1643 struct wlp
*wlp
= frame_ctx
->wlp
;
1644 struct wlp_wss
*wss
= &wlp
->wss
;
1645 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1646 struct wlp_frame_assoc
*c1
= (void *) frame_ctx
->skb
->data
;
1647 unsigned int len
= frame_ctx
->skb
->len
;
1648 struct uwb_dev_addr
*src
= &frame_ctx
->src
;
1650 struct wlp_uuid wssid
;
1651 struct sk_buff
*resp
= NULL
;
1653 /* Parse C1 frame */
1654 mutex_lock(&wss
->mutex
);
1655 result
= wlp_get_wssid(wlp
, (void *)c1
+ sizeof(*c1
), &wssid
,
1658 dev_err(dev
, "WLP: unable to obtain WSSID from C1 frame.\n");
1661 if (!memcmp(&wssid
, &wss
->wssid
, sizeof(wssid
))
1662 && wss
->state
== WLP_WSS_STATE_ACTIVE
) {
1663 /* Construct C2 frame */
1664 result
= wlp_build_assoc_c2(wlp
, wss
, &resp
);
1666 dev_err(dev
, "WLP: Unable to construct C2 message.\n");
1670 /* Construct F0 frame */
1671 result
= wlp_build_assoc_f0(wlp
, &resp
, WLP_ASSOC_ERROR_INV
);
1673 dev_err(dev
, "WLP: Unable to construct F0 message.\n");
1678 BUG_ON(wlp
->xmit_frame
== NULL
);
1679 result
= wlp
->xmit_frame(wlp
, resp
, src
);
1681 dev_err(dev
, "WLP: Unable to transmit response association "
1682 "message: %d\n", result
);
1683 if (result
== -ENXIO
)
1684 dev_err(dev
, "WLP: Is network interface up? \n");
1685 /* We could try again ... */
1686 dev_kfree_skb_any(resp
); /* we need to free if tx fails */
1689 kfree_skb(frame_ctx
->skb
);
1691 mutex_unlock(&wss
->mutex
);
1695 * Handle incoming C3 frame
1697 * The frame has already been verified to contain an Association header with
1698 * the correct version number. Parse the incoming frame, construct and send
1699 * a C4 frame in response. If the C3 frame identifies a WSS that is locally
1700 * active then we connect to this neighbor (add it to our EDA cache).
1702 void wlp_handle_c3_frame(struct work_struct
*ws
)
1704 struct wlp_assoc_frame_ctx
*frame_ctx
= container_of(ws
,
1705 struct wlp_assoc_frame_ctx
,
1707 struct wlp
*wlp
= frame_ctx
->wlp
;
1708 struct wlp_wss
*wss
= &wlp
->wss
;
1709 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
1710 struct sk_buff
*skb
= frame_ctx
->skb
;
1711 struct uwb_dev_addr
*src
= &frame_ctx
->src
;
1713 struct sk_buff
*resp
= NULL
;
1714 struct wlp_uuid wssid
;
1716 struct uwb_mac_addr virt_addr
;
1718 /* Parse C3 frame */
1719 mutex_lock(&wss
->mutex
);
1720 result
= wlp_parse_c3c4_frame(wlp
, skb
, &wssid
, &tag
, &virt_addr
);
1722 dev_err(dev
, "WLP: unable to obtain values from C3 frame.\n");
1725 if (!memcmp(&wssid
, &wss
->wssid
, sizeof(wssid
))
1726 && wss
->state
>= WLP_WSS_STATE_ACTIVE
) {
1727 result
= wlp_eda_update_node(&wlp
->eda
, src
, wss
,
1728 (void *) virt_addr
.data
, tag
,
1731 dev_err(dev
, "WLP: Unable to update EDA cache "
1732 "with new connected neighbor information.\n");
1733 result
= wlp_build_assoc_f0(wlp
, &resp
,
1734 WLP_ASSOC_ERROR_INT
);
1736 dev_err(dev
, "WLP: Unable to construct F0 "
1741 wss
->state
= WLP_WSS_STATE_CONNECTED
;
1742 /* Construct C4 frame */
1743 result
= wlp_build_assoc_c4(wlp
, wss
, &resp
);
1745 dev_err(dev
, "WLP: Unable to construct C4 "
1751 /* Construct F0 frame */
1752 result
= wlp_build_assoc_f0(wlp
, &resp
, WLP_ASSOC_ERROR_INV
);
1754 dev_err(dev
, "WLP: Unable to construct F0 message.\n");
1759 BUG_ON(wlp
->xmit_frame
== NULL
);
1760 result
= wlp
->xmit_frame(wlp
, resp
, src
);
1762 dev_err(dev
, "WLP: Unable to transmit response association "
1763 "message: %d\n", result
);
1764 if (result
== -ENXIO
)
1765 dev_err(dev
, "WLP: Is network interface up? \n");
1766 /* We could try again ... */
1767 dev_kfree_skb_any(resp
); /* we need to free if tx fails */
1770 kfree_skb(frame_ctx
->skb
);
1772 mutex_unlock(&wss
->mutex
);