wimax-tools 1.4.4

/home/users/builder/rpm/BUILD/wimax-tools-1.4.4/include/wimaxll.h

Go to the documentation of this file.
00001 /*
00002  * Linux WiMax
00003  * User Space API
00004  *
00005  *
00006  * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
00007  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above copyright
00016  *     notice, this list of conditions and the following disclaimer in
00017  *     the documentation and/or other materials provided with the
00018  *     distribution.
00019  *   * Neither the name of Intel Corporation nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *
00036  *
00037  */
00038 /**
00039  * @mainpage
00040  *
00041  * This is a simple library to control WiMAX devices through the
00042  * control API exported by the Linux kernel WiMAX Stack. It provides
00043  * means to execute functions exported by the stack and to receive its
00044  * notifications.
00045  *
00046  * Because of this, this is a callback oriented library. It is
00047  * designed to be operated asynchronously and/or in an event loop. For
00048  * the very simple cases, helpers that implement synchronous
00049  * functionality are available.
00050  *
00051  * This library is provided as a convenience and using it is not
00052  * required to talk to the WiMAX kernel stack. It is possible to do so
00053  * by interacting with it over generic netlink directly.
00054  *
00055  * \note this is a very low level library. It does not provide the
00056  * caller with means to scan, connect, disconnect, etc from a WiMAX
00057  * network. Said capability is provided by higher level services which
00058  * might be users of this library.
00059  *
00060  * @section conventions Conventions
00061  *
00062  * Most function calls return an integer with a negative \a errno
00063  * error code when there is an error.
00064  *
00065  * @section general_usage General usage
00066  *
00067  * The first operation to start controlling a WiMAX device is to open
00068  * a handle for it:
00069  *
00070  * @code
00071  *  struct wimaxll_handle *wmx = wimaxll_open("wmx0");
00072  * @endcode
00073  *
00074  * With an open handle you can execute all the WiMax API
00075  * operations. When done with the handle, it has to be closed:
00076  *
00077  * @code
00078  *  wimaxll_close(wmx);
00079  * @endcode
00080  *
00081  * If the device is unloaded/disconnected, the handle will be marked
00082  * as invalid and any operation will fail with -ENODEV.
00083  *
00084  * To reset a WiMAX device, use:
00085  *
00086  * @code
00087  *  wimaxll_reset(wmx);
00088  * @endcode
00089  *
00090  * To turn a device \e on or \e off, or to query it's status, use:
00091  *
00092  * @code
00093  *  wimaxll_rfkill(wmx, WIMAX_RF_ON);
00094  * @endcode
00095  *
00096  * WIMAX_RF_ON and WIMAX_RF_OFF turn the radio on and off
00097  * respectively, using the software switch and return the current
00098  * status of both switches. WIMAX_RF_QUERY just returns the status of
00099  * both the \e HW and \e SW switches.
00100  *
00101  * See \ref device_management "device management" for more information.
00102  *
00103  * \section receiving Receiving notifications from the WiMAX kernel stack
00104  *
00105  * The WiMAX kernel stack will broadcast notifications and
00106  * driver-specific messages to all the user space clients connected to
00107  * it over a generic netlink multicast group.
00108  *
00109  * To listen to said notifications, a library client needs to block
00110  * waiting for them or set \ref callbacks "callbacks" and integrate
00111  * into some kind of main loop using \e select() call to detect
00112  * incoming notifications.
00113  *
00114  * Simple example of mainloop integration:
00115  *
00116  * @code
00117  * int fd = wimaxll_recv_fd(wmx);
00118  * fd_set pipe_fds, read_fds;
00119  * ...
00120  * // Main loop
00121  * FD_ZERO(&pipe_fds);
00122  * FD_SET(fd, &pipe_fds);
00123  * while(1) {
00124  *         read_fds = pipe_fds;
00125  *         select(FD_SETSIZE, &read_fds, NULL, NULL, NULL);
00126  *         if (FD_ISSET(fd, &read_fds))
00127  *                 wimaxll_recv(wmx);
00128  * }
00129  * @endcode
00130  *
00131  * This code will call wimaxll_recv() when notifications are available
00132  * for delivery. Calling said function will execute, for each
00133  * notification, the callback associated to it.
00134  *
00135  * To wait for a \e state \e change notification, for example:
00136  *
00137  * @code
00138  * result = wimaxll_wait_for_state_change(wmx, &old_state, &new_state);
00139  * @endcode
00140  *
00141  * The same thing can be accomplished setting a callback for a state
00142  * change notification with wimaxll_set_cb_state_change() and then
00143  * waiting on a main loop. See \ref state_change_group "state changes"
00144  * for more information.
00145  *
00146  * To wait for a (device-specific) message from the driver, an
00147  * application would use:
00148  *
00149  * @code
00150  * void *msg;
00151  * ...
00152  *
00153  * size = wimaxll_msg_read(wmx, &msg);
00154  *
00155  * ... <act on the message>
00156  *
00157  * wimaxll_msg_free(msg);            // done with the message
00158  * @endcode
00159  *
00160  * \e msg points to a buffer which contains the message payload as
00161  * sent by the driver. When done with \a msg it has to be freed with
00162  * wimaxll_msg_free().
00163  *
00164  * As with \e state \e change notifications, a callback can be set
00165  * that will be executed from a mainloop every time a message is
00166  * received from a message pipe. See
00167  * wimaxll_pipe_set_cb_msg_to_user().
00168  *
00169  * A message can be sent to the driver with wimaxll_msg_write().
00170  * not the default \e message pipe.
00171  *
00172  * For more details, see \ref the_messaging_interface.
00173  *
00174  * @section miscellaneous Miscellaneous
00175  *
00176  * @subsection diagnostics Controlling the ouput of diagnostics
00177  *
00178  * \e libwimaxll will output messages by default to \a stderr. See
00179  * \ref helper_log for changing the default destination.
00180  *
00181  * @subsection bytesex Endianess conversion
00182  *
00183  * The following convenience helpers are provided for endianess
00184  * conversion:
00185  *
00186  * - wimaxll_le32_to_cpu() and wimaxll_cpu_to_le32()
00187  * - wimaxll_le16_to_cpu() and wimaxll_cpu_to_le16()
00188  * - wimaxll_swap_16() and wimaxll_swap_32()
00189  *
00190  * @section multithreading Multithreading
00191  *
00192  * This library is not threaded or locked. Internally it uses two
00193  * different netlink handles, one for receiving and one for sending;
00194  * thus the maximum level of paralellism you can do with one handle
00195  * is:
00196  *
00197  * - Functions that can't be executed in parallel when using the same
00198  *   wimaxll handle (need to be serialized):
00199  *   <ul>
00200  *     <li> wimaxll_msg_write(), wimaxll_rfkill(), wimax_reset()
00201  *     <li> wimaxll_recv(), wimaxll_msg_read(),
00202  *          wimaxll_wait_for_state_change()
00203  *     <li> wimax_get_cb_*() and wimax_set_cb_*().
00204  *     <li> wimaxll_recv_fd(), as long as the handle is valid.
00205  *   </ul>
00206  *
00207  * - Function calls that have to be always serialized with respect to
00208  *   any other:
00209  *   <ul>
00210  *     <li> wimaxll_open() and wimaxll_close()
00211  *     <li> wimax_get_cb_*() and wimax_set_cb_*().
00212  *   </ul>
00213  *
00214  * - callbacks are all executed serially; don't call wimax_recv() from
00215  *   inside a callback.
00216  *
00217  * Any function not covered by the in this list can be parallelizable.
00218  */
00219 
00220 
00221 #ifndef __lib_wimaxll_h__
00222 #define __lib_wimaxll_h__
00223 #include <sys/errno.h>
00224 #include <sys/types.h>
00225 #include <endian.h>
00226 #include <byteswap.h>
00227 #include <stdarg.h>
00228 #include <linux/wimax.h>
00229 
00230 struct wimaxll_handle;
00231 
00232 struct nlattr;
00233 
00234 
00235 /**
00236  * \defgroup callbacks Callbacks
00237  *
00238  * When notification callbacks are being executed, the processing of
00239  * notifications from the kernel is effectively blocked by it. Care
00240  * must be taken not to call blocking functions, especially
00241  * wimaxll_recv().
00242  *
00243  * Callbacks are always passed a pointer to a private context as set
00244  * by the application.
00245  *
00246  * Callbacks can return -%EBUSY to have wimaxll_recv() stop processing
00247  * messages and pass control to the caller (which will see it
00248  * returning -%EBUSY). Callbacks *SHOULD NOT* return -%EINPROGRESS, as
00249  * it is used internally by wimaxll_recv().
00250  */
00251 
00252 
00253 /**
00254  * Callback for a \e message \e to \e user generic netlink message
00255  *
00256  * A \e driver \e specific message has been received from the kernel;
00257  * the pointer to the data and the size are passed in \a data and \a
00258  * size. The callback can access that data, but it's lifetime is valid
00259  * only while the callback is executing. If it will be accessed later,
00260  * it has to be copied to a safe location.
00261  *
00262  * \note See \ref callbacks callbacks for a set of warnings and
00263  * guidelines for using callbacks.
00264  *
00265  * \param wmx WiMAX device handle
00266  * \param priv Context passed by the user with
00267  *     wimaxll_pipe_set_cb_msg_to_user().
00268  * \param pipe_name Name of the pipe the message is sent for
00269  * \param data Pointer to a buffer with the message data.
00270  * \param size Size of the buffer
00271  * \return >= 0 if it is ok to keep processing messages, -EBUSY if
00272  *     message processing should stop and control be returned to the
00273  *     caller. Any other negative error code to continue processing
00274  *     messages skipping the current one.
00275  *
00276  * \ingroup the_messaging_interface
00277  */
00278 typedef int (*wimaxll_msg_to_user_cb_f)(struct wimaxll_handle *wmx,
00279                                         void *priv,
00280                                         const char *pipe_name,
00281                                         const void *data, size_t size);
00282 
00283 /**
00284  * Callback for a \e state \e change notification from the WiMAX
00285  * kernel stack.
00286  *
00287  * The WiMAX device has changed state from \a old_state to \a
00288  * new_state.
00289  *
00290  * \note See \ref callbacks callbacks for a set of warnings and
00291  * guidelines for using callbacks.
00292  *
00293  * \param wmx WiMAX device handle
00294  * \param priv ctx Context passed by the user with
00295  *     wimaxll_set_cb_state_change().
00296  * \param old_state State the WiMAX device left
00297  * \param new_state State the WiMAX device entered
00298  * \return >= 0 if it is ok to keep processing messages, -EBUSY if
00299  *     message processing should stop and control be returned to the
00300  *     caller. Any other negative error code to continue processing
00301  *     messages skipping the current one.
00302  *
00303  * \ingroup state_change_group
00304  */
00305 typedef int (*wimaxll_state_change_cb_f)(
00306         struct wimaxll_handle *, void *priv,
00307         enum wimax_st old_state, enum wimax_st new_state);
00308 
00309 
00310 /* Basic handle management */
00311 struct wimaxll_handle *wimaxll_open(const char *device_name);
00312 void *wimaxll_priv_get(struct wimaxll_handle *);
00313 void wimaxll_priv_set(struct wimaxll_handle *, void *);
00314 void wimaxll_close(struct wimaxll_handle *);
00315 const char *wimaxll_ifname(const struct wimaxll_handle *);
00316 unsigned wimaxll_ifidx(const struct wimaxll_handle *);
00317 
00318 /* Wait for data from the kernel, execute callbacks */
00319 int wimaxll_recv_fd(struct wimaxll_handle *);
00320 ssize_t wimaxll_recv(struct wimaxll_handle *);
00321 
00322 /* Default (bidirectional) message pipe from the kernel */
00323 ssize_t wimaxll_msg_write(struct wimaxll_handle *, const char *,
00324                           const void *, size_t);
00325 
00326 void wimaxll_get_cb_msg_to_user(struct wimaxll_handle *,
00327                                 wimaxll_msg_to_user_cb_f *, void **);
00328 void wimaxll_set_cb_msg_to_user(struct wimaxll_handle *,
00329                                 wimaxll_msg_to_user_cb_f, void *);
00330 
00331 #define WIMAX_PIPE_ANY (NULL-1)
00332 ssize_t wimaxll_msg_read(struct wimaxll_handle *, const char *pine_name,
00333                          void **);
00334 void wimaxll_msg_free(void *);
00335 
00336 /* generic API */
00337 int wimaxll_rfkill(struct wimaxll_handle *, enum wimax_rf_state);
00338 int wimaxll_reset(struct wimaxll_handle *);
00339 int wimaxll_state_get(struct wimaxll_handle *);
00340 
00341 void wimaxll_get_cb_state_change(
00342         struct wimaxll_handle *, wimaxll_state_change_cb_f *,
00343         void **);
00344 void wimaxll_set_cb_state_change(
00345         struct wimaxll_handle *, wimaxll_state_change_cb_f,
00346         void *);
00347 ssize_t wimaxll_wait_for_state_change(struct wimaxll_handle *wmx,
00348                                       enum wimax_st *old_state,
00349                                       enum wimax_st *new_state);
00350 
00351 
00352 /**
00353  * \defgroup miscellaneous_group Miscellaneous utilities
00354  */
00355 enum wimax_st wimaxll_state_by_name(const char *);
00356 size_t wimaxll_states_snprintf(char *, size_t);
00357 const char * wimaxll_state_to_name(enum wimax_st);
00358 
00359 #define wimaxll_array_size(a) (sizeof(a)/sizeof(a[0]))
00360 
00361 #define wimaxll_container_of(pointer, type, member)                     \
00362 ({                                                                      \
00363         type *object = NULL;                                            \
00364         size_t offset = (void *) &object->member - (void *) object;     \
00365         (type *) ((void *) pointer - offset);                           \
00366 })
00367 
00368 static inline   // ugly hack for doxygen
00369 /**
00370  *
00371  * Swap the nibbles in a 16 bit number.
00372  *
00373  * \ingroup miscellaneous_group
00374  * \fn unsigned short wimaxll_swap_16(unsigned short x)
00375  */
00376 unsigned short wimaxll_swap_16(unsigned short x)
00377 {
00378         return bswap_16(x);
00379 }
00380 
00381 
00382 static inline   // ugly hack for doxygen
00383 /**
00384  * Swap the nibbles in a 32 bit number.
00385  *
00386  * \ingroup miscellaneous_group
00387  * \fn unsigned long wimaxll_swap_32(unsigned long x)
00388  */
00389 unsigned long wimaxll_swap_32(unsigned long x)
00390 {
00391         return bswap_32(x);
00392 }
00393 
00394 
00395 static inline   // ugly hack for doxygen
00396 /**
00397  * Convert a cpu-order 16 bits to little endian.
00398  *
00399  * \ingroup miscellaneous_group
00400  * \fn unsigned short wimaxll_cpu_to_le16(unsigned short x)
00401  */
00402 unsigned short wimaxll_cpu_to_le16(unsigned short x)
00403 {
00404         unsigned short le16;
00405 #if __BYTE_ORDER == __LITTLE_ENDIAN
00406         le16 = x;
00407 #elif __BYTE_ORDER == __BIG_ENDIAN
00408         le16 = wimaxll_swap_16(x);
00409 #else
00410 #error ERROR: unknown byte sex - FIXME
00411 #endif
00412         return le16;
00413 }
00414 
00415 
00416 static inline   // ugly hack for doxygen
00417 /**
00418  * Convert a little-endian 16 bits to cpu order.
00419  *
00420  * \ingroup miscellaneous_group
00421  * \fn unsigned short wimaxll_le16_to_cpu(unsigned short le16)
00422  */
00423 unsigned short wimaxll_le16_to_cpu(unsigned short le16)
00424 {
00425         unsigned short cpu;
00426 #if __BYTE_ORDER == __LITTLE_ENDIAN
00427         cpu = le16;
00428 #elif __BYTE_ORDER == __BIG_ENDIAN
00429         cpu = wimaxll_swap_16(le16);
00430 #else
00431 #error ERROR: unknown byte sex - FIXME
00432 #endif
00433         return cpu;
00434 }
00435 
00436 
00437 static inline   // ugly hack for doxygen
00438 /**
00439  * Convert a cpu-order 32 bits to little endian.
00440  *
00441  * \ingroup miscellaneous_group
00442  * \fn unsigned long wimaxll_cpu_to_le32(unsigned long x)
00443  */
00444 unsigned long wimaxll_cpu_to_le32(unsigned long x)
00445 {
00446         unsigned long le32;
00447 #if __BYTE_ORDER == __LITTLE_ENDIAN
00448         le32 = x;
00449 #elif __BYTE_ORDER == __BIG_ENDIAN
00450         le32 = wimaxll_swap_32(x);
00451 #else
00452 #error ERROR: unknown byte sex - FIXME
00453 #endif
00454         return le32;
00455 }
00456 
00457 
00458 static inline   // ugly hack for doxygen
00459 /**
00460  * Convert a little-endian 32 bits to cpu order.
00461  *
00462  * \ingroup miscellaneous_group
00463  * \fn unsigned long wimaxll_le32_to_cpu(unsigned long le32)
00464  */
00465 unsigned long wimaxll_le32_to_cpu(unsigned long le32)
00466 {
00467         unsigned long cpu;
00468 #if __BYTE_ORDER == __LITTLE_ENDIAN
00469         cpu = le32;
00470 #elif __BYTE_ORDER == __BIG_ENDIAN
00471         cpu = wimaxll_swap_32(le32);
00472 #else
00473 #error ERROR: unknown byte sex - FIXME
00474 #endif
00475         return cpu;
00476 }
00477 
00478 
00479 static inline   // ugly hack for doxygen
00480 /**
00481  * Convert a cpu-order 16 bits to big endian.
00482  *
00483  * \ingroup miscellaneous_group
00484  * \fn unsigned short wimaxll_cpu_to_be16(unsigned short x)
00485  */
00486 unsigned short wimaxll_cpu_to_be16(unsigned short x)
00487 {
00488         unsigned short be16;
00489 #if __BYTE_ORDER == __LITTLE_ENDIAN
00490         be16 = wimaxll_swap_16(x);
00491 #elif __BYTE_ORDER == __BIG_ENDIAN
00492         be16 = x;
00493 #else
00494 #error ERROR: unknown byte sex - FIXME
00495 #endif
00496         return be16;
00497 }
00498 
00499 
00500 static inline   // ugly hack for doxygen
00501 /**
00502  * Convert a big-endian 16 bits to cpu order.
00503  *
00504  * \ingroup miscellaneous_group
00505  * \fn unsigned short wimaxll_be16_to_cpu(unsigned short be16)
00506  */
00507 unsigned short wimaxll_be16_to_cpu(unsigned short be16)
00508 {
00509         unsigned short cpu;
00510 #if __BYTE_ORDER == __LITTLE_ENDIAN
00511         cpu = wimaxll_swap_16(be16);
00512 #elif __BYTE_ORDER == __BIG_ENDIAN
00513         cpu = be16;
00514 #else
00515 #error ERROR: unknown byte sex - FIXME
00516 #endif
00517         return cpu;
00518 }
00519 
00520 
00521 static inline   // ugly hack for doxygen
00522 /**
00523  * Convert a cpu-order 32 bits to big endian.
00524  *
00525  * \ingroup miscellaneous_group
00526  * \fn unsigned long wimaxll_cpu_to_be32(unsigned long x)
00527  */
00528 unsigned long wimaxll_cpu_to_be32(unsigned long x)
00529 {
00530         unsigned long be32;
00531 #if __BYTE_ORDER == __LITTLE_ENDIAN
00532         be32 = wimaxll_swap_32(x);
00533 #elif __BYTE_ORDER == __BIG_ENDIAN
00534         be32 = x;
00535 #else
00536 #error ERROR: unknown byte sex - FIXME
00537 #endif
00538         return be32;
00539 }
00540 
00541 
00542 static inline   // ugly hack for doxygen
00543 /**
00544  * Convert a big-endian 32 bits to cpu order.
00545  *
00546  * \ingroup miscellaneous_group
00547  * \fn unsigned long wimaxll_be32_to_cpu(unsigned long be32)
00548  */
00549 unsigned long wimaxll_be32_to_cpu(unsigned long be32)
00550 {
00551         unsigned long cpu;
00552 #if __BYTE_ORDER == __LITTLE_ENDIAN
00553         cpu = be32;
00554 #elif __BYTE_ORDER == __BIG_ENDIAN
00555         cpu = wimaxll_swap_32(be32);
00556 #else
00557 #error ERROR: unknown byte sex - FIXME
00558 #endif
00559         return cpu;
00560 }
00561 
00562 
00563 #define __WIMAXLL_ALIGN2_MASK(n, m) (((n) + (m)) & ~(m))
00564 /**
00565  * Return the value \e n aligned to an order-of-two value \a o2.
00566  */
00567 #define WIMAXLL_ALIGN2(n, o2) __WIMAXLL_ALIGN2_MASK(n, (typeof(n)) (o2) - 1)
00568 
00569 #endif /* #ifndef __lib_wimaxll_h__ */