shill: Parses nl80211 nested attributes _way_ better than before.

Adds code to parse nested attributes using tables.  Makes the whole
nested attribute parsing thing much more readable.  Simplifies setting
up future nested attributes, reduces duplication and, potentially,
lots of bugs.  As part of this CL, the |AttributeList::Set*| and
|AttributeList::Create*| methods were made public.

There's at least one more CL coming to add custom parsing to
individual nested attributes.

BUG=chromium-os:37742
TEST=unittests.  Other unittests will be modified to utilize these
  changes in the next CL.

Change-Id: Icf2d234c189652dec56891c7e688ee4fef41191e
Reviewed-on: https://gerrit.chromium.org/gerrit/44132
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Queue: Wade Guthrie <wdg@chromium.org>
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
diff --git a/callback80211_metrics.cc b/callback80211_metrics.cc
index a309aa8..0583165 100644
--- a/callback80211_metrics.cc
+++ b/callback80211_metrics.cc
@@ -25,14 +25,14 @@
   if (metrics_ &&
       message.message_type() == DeauthenticateMessage::kCommand) {
     Metrics::WiFiDisconnectByWhom by_whom =
-        message.attributes().IsFlagAttributeTrue(
+        message.const_attributes()->IsFlagAttributeTrue(
             NL80211_ATTR_DISCONNECTED_BY_AP) ?
                     Metrics::kDisconnectedByAp : Metrics::kDisconnectedNotByAp;
     uint16_t reason = static_cast<uint16_t>(
         IEEE_80211::kReasonCodeInvalid);
     ByteString rawdata;
-    if (message.attributes().GetRawAttributeValue(NL80211_ATTR_FRAME,
-                                                  &rawdata)) {
+    if (message.const_attributes()->GetRawAttributeValue(NL80211_ATTR_FRAME,
+                                                         &rawdata)) {
       Nl80211Frame frame(rawdata);
       reason = frame.reason();
     }