Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "wificond/net/mlme_event.h"
     18 
     19 #include <vector>
     20 
     21 #include <android-base/logging.h>
     22 
     23 #include "wificond/net/kernel-header-latest/nl80211.h"
     24 #include "wificond/net/nl80211_packet.h"
     25 
     26 using std::unique_ptr;
     27 using std::vector;
     28 
     29 namespace android {
     30 namespace wificond {
     31 
     32 namespace {
     33 
     34 bool GetCommonFields(const NL80211Packet* packet,
     35                      uint32_t* if_index,
     36                      vector<uint8_t>* bssid) {
     37   if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, if_index)) {
     38      LOG(ERROR) << "Failed to get NL80211_ATTR_IFINDEX";
     39      return false;
     40   }
     41   // Some MLME events do not contain MAC address.
     42   if (!packet->GetAttributeValue(NL80211_ATTR_MAC, bssid)) {
     43     LOG(DEBUG) << "Failed to get NL80211_ATTR_MAC";
     44   }
     45   return true;
     46 }
     47 
     48 }  // namespace
     49 
     50 unique_ptr<MlmeAssociateEvent> MlmeAssociateEvent::InitFromPacket(
     51     const NL80211Packet* packet) {
     52   if (packet->GetCommand() != NL80211_CMD_ASSOCIATE) {
     53     return nullptr;
     54   }
     55   unique_ptr<MlmeAssociateEvent> associate_event(new MlmeAssociateEvent());
     56 
     57   if (!GetCommonFields(packet,
     58                        &(associate_event->interface_index_),
     59                        &(associate_event->bssid_))){
     60     return nullptr;
     61   }
     62   // According to wpa_supplicant, status code of an ASSOCIATE event should be
     63   // parsed from NL80211_ATTR_FRAME attribute.
     64   // TODO(nywang): Parse NL80211_ATTR_FRAME 80211 management frame and get
     65   // status code.
     66   associate_event->status_code_ = 0;
     67   associate_event->is_timeout_ = packet->HasAttribute(NL80211_ATTR_TIMED_OUT);
     68 
     69   return associate_event;
     70 }
     71 
     72 unique_ptr<MlmeConnectEvent> MlmeConnectEvent::InitFromPacket(
     73     const NL80211Packet* packet) {
     74   if (packet->GetCommand() != NL80211_CMD_CONNECT) {
     75     return nullptr;
     76   }
     77   unique_ptr<MlmeConnectEvent> connect_event(new MlmeConnectEvent());
     78   if (!GetCommonFields(packet,
     79                        &(connect_event->interface_index_),
     80                        &(connect_event->bssid_))){
     81     return nullptr;
     82   }
     83 
     84   if (!packet->GetAttributeValue(NL80211_ATTR_STATUS_CODE,
     85                                  &(connect_event->status_code_))) {
     86     LOG(WARNING) << "Failed to get NL80211_ATTR_STATUS_CODE";
     87     connect_event->status_code_ = 0;
     88   }
     89   connect_event->is_timeout_ = packet->HasAttribute(NL80211_ATTR_TIMED_OUT);
     90 
     91   return connect_event;
     92 }
     93 
     94 unique_ptr<MlmeRoamEvent> MlmeRoamEvent::InitFromPacket(
     95     const NL80211Packet* packet) {
     96   if (packet->GetCommand() != NL80211_CMD_ROAM) {
     97     return nullptr;
     98   }
     99   unique_ptr<MlmeRoamEvent> roam_event(new MlmeRoamEvent());
    100   if (!GetCommonFields(packet,
    101                        &(roam_event->interface_index_),
    102                        &(roam_event->bssid_))){
    103     return nullptr;
    104   }
    105 
    106   return roam_event;
    107 }
    108 
    109 unique_ptr<MlmeDisconnectEvent> MlmeDisconnectEvent::InitFromPacket(
    110     const NL80211Packet* packet) {
    111   if (packet->GetCommand() != NL80211_CMD_DISCONNECT) {
    112     return nullptr;
    113   }
    114   unique_ptr<MlmeDisconnectEvent> disconnect_event(new MlmeDisconnectEvent());
    115   if (!GetCommonFields(packet,
    116                        &(disconnect_event->interface_index_),
    117                        &(disconnect_event->bssid_))){
    118     return nullptr;
    119   }
    120   return disconnect_event;
    121 }
    122 
    123 unique_ptr<MlmeDisassociateEvent> MlmeDisassociateEvent::InitFromPacket(
    124     const NL80211Packet* packet) {
    125   if (packet->GetCommand() != NL80211_CMD_DISASSOCIATE) {
    126     return nullptr;
    127   }
    128   unique_ptr<MlmeDisassociateEvent> disassociate_event(new MlmeDisassociateEvent());
    129   if (!GetCommonFields(packet,
    130                        &(disassociate_event->interface_index_),
    131                        &(disassociate_event->bssid_))){
    132     return nullptr;
    133   }
    134   return disassociate_event;
    135 }
    136 
    137 }  // namespace wificond
    138 }  // namespace android
    139