wimax-tools  1.4.4
Functions
Helpers to control an Intel 2400m based device

This set of helpers simplify the task of sending commands / waiting for the acks and receiving reports/indications from the i2400m. More...

Functions

int i2400m_create (struct i2400m **_i2400m, const char *ifname, void *priv, i2400m_report_cb report_cb)
 Create a i2400m handle. More...
 
int i2400m_create_from_handle (struct i2400m **_i2400m, struct wimaxll_handle *wmx, void *priv, i2400m_report_cb report_cb)
 Create a i2400m handle from an existing WiMAX handle. More...
 
void i2400m_destroy (struct i2400m *i2400m)
 Destroy a descriptor created with i2400m_create() More...
 
void * i2400m_priv (struct i2400m *i2400m)
 Return the private data associated to a i2400m. More...
 
struct wimaxll_handlei2400m_wmx (struct i2400m *i2400m)
 Return the libwimaxll handle associated to a i2400m. More...
 
int i2400m_msg_to_dev (struct i2400m *i2400m, const struct i2400m_l3l4_hdr *l3l4, size_t l3l4_size, i2400m_reply_cb cb, void *cb_priv)
 Execute an i2400m command and wait for a response. More...
 
ssize_t i2400m_tlv_match (const struct i2400m_tlv_hdr *tlv, enum i2400m_tlv tlv_type, ssize_t tlv_size)
 Return if a TLV is of a give type and size. More...
 
struct i2400m_tlv_hdr * i2400m_tlv_buffer_walk (const void *tlv_buf, size_t buf_size, const struct i2400m_tlv_hdr *tlv_pos)
 Iterate over a buffer of TLVs. More...
 
struct i2400m_tlv_hdr * i2400m_tlv_find (const struct i2400m_tlv_hdr *tlv_hdr, size_t size, enum i2400m_tlv tlv_type, ssize_t tlv_size)
 Find a TLV by type (and maybe length) in a buffer of TLVs. More...
 

Detailed Description

This set of helpers simplify the task of sending commands / waiting for the acks and receiving reports/indications from the i2400m.

It boils down to a framework to support that only one thread can send a command at the same time; this is because the commands don't have a cookie to identify the issuer – so a place is needed where to store the "I am waiting for a response for command X".

When the callback from libwimaxll comes back with the response, if it was a reply to said message, then the waiter for that is woken up (using pthread mutexes and conditional variables). See Thread cancellation for more information on what happens when the thread is cancelled.

When a report is received, the report callback is called; care has to be taken not to deadlock. See i2400m_report_cb().

For usage, create a handle:

* {
* int r;
* struct i2400m *i2400m;
* ...
* r = i2400m_create(&i2400m, "wmx0", my_priv_pointer, my_report_cb);
* if (r < 0)
* error;
* ...
* // create a message
* ...
* r = i2400m_msg_to_dev(i2400m, &message, message_size,
* message_cb, message_cb_priv);
* if (r < 0)
* error;
* // message_cb has been called
* i2400m_destroy(i2400m);
* }
*

Remember there are limited things that can be done in the callback; calling i2400m_msg_to_dev() will deadlock, as well as waiting for a report.

A report callback with some TLV processing example would be:

* static
* void my_report_cb(struct i2400m *i2400m,
* const struct i2400m_l3l4_hdr *l3l4, size_t l3l4_size)
* {
* struct my_priv *my_priv = i2400m_priv(i2400m);
* struct wimaxll_handle *wmx = i2400m_wmx(i2400m);
*
* // do something with the report...;
*
* struct i2400m_tlv *tlv = NULL;
*
* while ((tlv = i2400m_tlv_buffer_walk(l3l4->pl, l3l4_size, tlv))) {
* tlv_type = wimaxll_le16_to_cpu(tlv->type);
* tlv_length = wimaxll_le16_to_cpu(tlv->length);
* // do whatever with the tlv
* }
*
* // or find a tlv in a buffer
* tlv = i2400m_tlv_find(l3l4->pl, l3l4_size - sizeof(*l3l4),
* I2400M_TLV_SOMETHING, -1);
*
* }
*

Thread cancellation

All the code that takes mutexes pushes a cleanup handler that will unlock the mutex if the thread is cancelled. This is designed to work only with deferred thread cancellation models. Check POSIX for more information.

Function Documentation

int i2400m_create ( struct i2400m **  _i2400m,
const char *  ifname,
void *  priv,
i2400m_report_cb  report_cb 
)

Create a i2400m handle.

Creates a handle usable to execute commands and use the i2400m helpers.

Parameters
_i2400mwhere to store the handler value (pointer to the descriptor).
ifnamename of the network interface where the i2400m is
privPointer that the callbacks can recover from the handle with i2400m_priv()
report_cbCallback function called when a report arrives
int i2400m_create_from_handle ( struct i2400m **  _i2400m,
struct wimaxll_handle wmx,
void *  priv,
i2400m_report_cb  report_cb 
)

Create a i2400m handle from an existing WiMAX handle.

Creates a handle usable to execute commands and use the i2400m helpers.

Parameters
_i2400mwhere to store the handler value (pointer to the descriptor).
wmxWiMAX handle to use
privPointer that the callbacks can recover from the handle with i2400m_priv()
report_cbCallback function called when a report arrives
void i2400m_destroy ( struct i2400m *  i2400m)

Destroy a descriptor created with i2400m_create()

Parameters
i2400mHandle for an i2400m as returned by i2400m_create().
int i2400m_msg_to_dev ( struct i2400m *  i2400m,
const struct i2400m_l3l4_hdr *  l3l4,
size_t  l3l4_size,
i2400m_reply_cb  cb,
void *  cb_priv 
)

Execute an i2400m command and wait for a response.

Parameters
i2400mi2400m handle
l3l4Pointer to buffer containing a L3L4 message to send to the device.
l3l4_sizesize of the buffer pointed to by l3l4 (this includes the message header and the TLV payloads, if any)
cbCallback function to execute when the reply is received.
cb_privPrivate pointer to pass to the callback function.

If the message execution fails in the device, the return value from wimaxll_msg_write() will tell it. It can also be taken (with more detail) by setting a callback function and parsing the reply.

This call can be executed from multiple threads on the same i2400m handle at the same time, as it will be mutexed properly and only one will execute at the same time (likewise, the driver will make sure only one command from different threads is ran at the same time).

Note

This call blocks waiting for the reply to the message; from the callback context no calls to i2400m_msg_dev() or waits for reports on the same handle as the callback can be done, as it would deadlock.

void* i2400m_priv ( struct i2400m *  i2400m)

Return the private data associated to a i2400m.

Parameters
i2400mi2400m handle
Returns
pointer to priv data as set at i2400m_create() time
struct i2400m_tlv_hdr* i2400m_tlv_buffer_walk ( const void *  tlv_buf,
size_t  buf_size,
const struct i2400m_tlv_hdr *  tlv_pos 
)

Iterate over a buffer of TLVs.

Allows to safely iterate over a buffer of TLVs, making sure bounds are properly checked. Usage:

* tlv_itr = NULL;
* while (tlv_itr = i2400m_tlv_buffer_walk(i2400m, buf, size, tlv_itr)) {
* ...
* // Do stuff with tlv_itr, DON'T MODIFY IT
* ...
* }
*
Parameters
tlv_bufpointer to the beginning of the TLV buffer
buf_sizebuffer size in bytes
tlv_posseek position; this is assumed to be a pointer returned by i2400m_tlv_buffer_walk() [and thus, validated]. The TLV returned will be the one following this one.
Returns
pointer to the next TLV from the seek position or NULL if the end of the buffer was reached.

Referenced by i2400m_tlv_find().

struct i2400m_tlv_hdr* i2400m_tlv_find ( const struct i2400m_tlv_hdr *  tlv_hdr,
size_t  size,
enum i2400m_tlv  tlv_type,
ssize_t  tlv_size 
)

Find a TLV by type (and maybe length) in a buffer of TLVs.

Parameters
tlv_hdrpointer to the first TLV in the sequence
sizesize of the buffer in bytes; all TLVs are assumed to fit fully in the buffer (otherwise we'll complain).
tlv_typetype of the TLV we are looking for
tlv_sizeexpected size of the TLV we are looking for (if -1, don't check the size). This includes the header
Returns
NULL if the TLV is not found, otherwise a pointer to it. If the sizes don't match, an error is printed and NULL returned.
ssize_t i2400m_tlv_match ( const struct i2400m_tlv_hdr *  tlv,
enum i2400m_tlv  tlv_type,
ssize_t  tlv_size 
)

Return if a TLV is of a give type and size.

Parameters
tlvpointer to the TLV
tlv_typetype of the TLV we are looking for
tlv_sizeexpected size of the TLV we are looking for (if -1, don't check the size). Size includes the TLV header.
Returns
0 if the TLV matches, < 0 if it doesn't match at all, > 0 total TLV + payload size, if the type matches, but not the size

Referenced by i2400m_tlv_find().

struct wimaxll_handle* i2400m_wmx ( struct i2400m *  i2400m)

Return the libwimaxll handle associated to a i2400m.

Parameters
i2400mi2400m handle
Returns
wimaxll handle