Home | History | Annotate | Download | only in wifi_hal
      1 
      2 #include <stdlib.h>
      3 #include <linux/pkt_sched.h>
      4 #include <netlink/object-api.h>
      5 #include <netlink/handlers.h>
      6 
      7 #include "wifi_hal.h"
      8 #include "common.h"
      9 
     10 interface_info *getIfaceInfo(wifi_interface_handle handle)
     11 {
     12     return (interface_info *)handle;
     13 }
     14 
     15 wifi_handle getWifiHandle(wifi_interface_handle handle)
     16 {
     17     return getIfaceInfo(handle)->handle;
     18 }
     19 
     20 hal_info *getHalInfo(wifi_handle handle)
     21 {
     22     return (hal_info *)handle;
     23 }
     24 
     25 hal_info *getHalInfo(wifi_interface_handle handle)
     26 {
     27     return getHalInfo(getWifiHandle(handle));
     28 }
     29 
     30 wifi_handle getWifiHandle(hal_info *info)
     31 {
     32     return (wifi_handle)info;
     33 }
     34 
     35 wifi_interface_handle getIfaceHandle(interface_info *info)
     36 {
     37     return (wifi_interface_handle)info;
     38 }
     39 
     40 wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
     41 {
     42     hal_info *info = (hal_info *)handle;
     43 
     44     /* TODO: check for multiple handlers? */
     45     pthread_mutex_lock(&info->cb_lock);
     46 
     47     wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
     48 
     49     if (info->num_event_cb < info->alloc_event_cb) {
     50         info->event_cb[info->num_event_cb].nl_cmd  = cmd;
     51         info->event_cb[info->num_event_cb].vendor_id  = 0;
     52         info->event_cb[info->num_event_cb].vendor_subcmd  = 0;
     53         info->event_cb[info->num_event_cb].cb_func = func;
     54         info->event_cb[info->num_event_cb].cb_arg  = arg;
     55         ALOGI("Successfully added event handler %p:%p for command %d at %d",
     56                 arg, func, cmd, info->num_event_cb);
     57         info->num_event_cb++;
     58         result = WIFI_SUCCESS;
     59     }
     60 
     61     pthread_mutex_unlock(&info->cb_lock);
     62     return result;
     63 }
     64 
     65 wifi_error wifi_register_vendor_handler(wifi_handle handle,
     66         uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
     67 {
     68     hal_info *info = (hal_info *)handle;
     69 
     70     /* TODO: check for multiple handlers? */
     71     pthread_mutex_lock(&info->cb_lock);
     72 
     73     wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
     74 
     75     if (info->num_event_cb < info->alloc_event_cb) {
     76         info->event_cb[info->num_event_cb].nl_cmd  = NL80211_CMD_VENDOR;
     77         info->event_cb[info->num_event_cb].vendor_id  = id;
     78         info->event_cb[info->num_event_cb].vendor_subcmd  = subcmd;
     79         info->event_cb[info->num_event_cb].cb_func = func;
     80         info->event_cb[info->num_event_cb].cb_arg  = arg;
     81         ALOGI("Added event handler %p:%p for vendor 0x%0x and subcmd 0x%0x at %d",
     82                 arg, func, id, subcmd, info->num_event_cb);
     83         info->num_event_cb++;
     84         result = WIFI_SUCCESS;
     85     }
     86 
     87     pthread_mutex_unlock(&info->cb_lock);
     88     return result;
     89 }
     90 
     91 void wifi_unregister_handler(wifi_handle handle, int cmd)
     92 {
     93     hal_info *info = (hal_info *)handle;
     94 
     95     if (cmd == NL80211_CMD_VENDOR) {
     96         ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
     97         return;
     98     }
     99 
    100     pthread_mutex_lock(&info->cb_lock);
    101 
    102     for (int i = 0; i < info->num_event_cb; i++) {
    103         if (info->event_cb[i].nl_cmd == cmd) {
    104             ALOGI("Successfully removed event handler %p:%p for cmd = 0x%0x from %d",
    105                     info->event_cb[i].cb_arg, info->event_cb[i].cb_func, cmd, i);
    106 
    107             memmove(&info->event_cb[i], &info->event_cb[i+1],
    108                 (info->num_event_cb - i - 1) * sizeof(cb_info));
    109             info->num_event_cb--;
    110             break;
    111         }
    112     }
    113 
    114     pthread_mutex_unlock(&info->cb_lock);
    115 }
    116 
    117 void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
    118 {
    119     hal_info *info = (hal_info *)handle;
    120 
    121     pthread_mutex_lock(&info->cb_lock);
    122 
    123     for (int i = 0; i < info->num_event_cb; i++) {
    124 
    125         if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
    126                 && info->event_cb[i].vendor_id == id
    127                 && info->event_cb[i].vendor_subcmd == subcmd) {
    128             ALOGI("Successfully removed event handler %p:%p for vendor 0x%0x, subcmd 0x%0x from %d",
    129                     info->event_cb[i].cb_arg, info->event_cb[i].cb_func, id, subcmd, i);
    130             memmove(&info->event_cb[i], &info->event_cb[i+1],
    131                 (info->num_event_cb - i - 1) * sizeof(cb_info));
    132             info->num_event_cb--;
    133             break;
    134         }
    135     }
    136 
    137     pthread_mutex_unlock(&info->cb_lock);
    138 }
    139 
    140 
    141 wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
    142 {
    143     hal_info *info = (hal_info *)handle;
    144 
    145     ALOGD("registering command %d", id);
    146 
    147     wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
    148 
    149     if (info->num_cmd < info->alloc_cmd) {
    150         info->cmd[info->num_cmd].id   = id;
    151         info->cmd[info->num_cmd].cmd  = cmd;
    152         ALOGI("Successfully added command %d: %p at %d", id, cmd, info->num_cmd);
    153         info->num_cmd++;
    154         result = WIFI_SUCCESS;
    155     }
    156 
    157     return result;
    158 }
    159 
    160 WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
    161 {
    162     hal_info *info = (hal_info *)handle;
    163 
    164     ALOGD("un-registering command %d", id);
    165 
    166     WifiCommand *cmd = NULL;
    167 
    168     for (int i = 0; i < info->num_cmd; i++) {
    169         if (info->cmd[i].id == id) {
    170             cmd = info->cmd[i].cmd;
    171             memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
    172             info->num_cmd--;
    173             ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
    174             break;
    175         }
    176     }
    177 
    178     return cmd;
    179 }
    180 
    181 WifiCommand *wifi_get_cmd(wifi_handle handle, int id)
    182 {
    183     hal_info *info = (hal_info *)handle;
    184 
    185     WifiCommand *cmd = NULL;
    186 
    187     for (int i = 0; i < info->num_cmd; i++) {
    188         if (info->cmd[i].id == id) {
    189             cmd = info->cmd[i].cmd;
    190             break;
    191         }
    192     }
    193 
    194     return cmd;
    195 }
    196 
    197 void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
    198 {
    199     hal_info *info = (hal_info *)handle;
    200 
    201     for (int i = 0; i < info->num_cmd; i++) {
    202         if (info->cmd[i].cmd == cmd) {
    203             int id = info->cmd[i].id;
    204             memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
    205             info->num_cmd--;
    206             ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
    207             break;
    208         }
    209     }
    210 }
    211