anchor.diff:  	    end
       end.
   
  -handle_capwap_packet(Packet, StateName, State = #state{ctrl_channel_address = WTPControlChannelAddress,
  -						       ctrl_stream = CtrlStreamState0}) ->
  +handle_capwap_packet(Packet, Data = #data{ctrl_channel_address = WTPControlChannelAddress,
  +					  ctrl_stream = CtrlStreamData0}) ->
       capwap_trace:trace(WTPControlChannelAddress, ?TRACE_LOCAL_CONTROL, Packet),
  -    case capwap_stream:recv(control, Packet, CtrlStreamState0) of
  -	{ok, {Header, Msg}, CtrlStreamState1} ->
  -	    handle_capwap_message(Header, Msg, StateName, State#state{ctrl_stream = CtrlStreamState1});
  -
  -	{ok, more, CtrlStreamState1} ->
  -	    next_state(StateName, State#state{ctrl_stream = CtrlStreamState1});
  +    case capwap_stream:recv(control, Packet, CtrlStreamData0) of
  +	{ok, {Header, Msg}, CtrlStreamData1} ->
  +	    handle_capwap_message(Header, Msg, Data#data{ctrl_stream = CtrlStreamData1});
  +
  +	{ok, more, CtrlStreamData1} ->
  +	    {keep_state, Data#data{ctrl_stream = CtrlStreamData1}};
   
   	{error, Error} ->
   	    lager:error([{capwap_packet, decode}, {error, Error}], "Decode error ~p", [Error]),
  -	    next_state(StateName, State)
  -    end.
  -
  -handle_capwap_message(Header, {Msg, 1, Seq, Elements}, StateName,
  -		      State0 = #state{last_response = LastResponse}) ->
  +	    keep_state_and_data
  +    end.
  +
  +-define(SEQ_LE(S1, S2), (S1 < S2 andalso (S2-S1) < 128) orelse (S1>S2 andalso (S1-S2) > 128)).
  +
  +handle_capwap_message(Header, {Msg, 1, Seq, Elements},
  +		      Data0 = #data{last_response = LastResponse}) ->
       %% Request
  -    ?log_capwap_control(peer_log_str(State0), Msg, Seq, Elements, Header),
  -    State = reset_echo_request_timer(State0),
  +    ?log_capwap_control(peer_log_str(Data0), Msg, Seq, Elements, Header),
  +    Data = reset_echo_request_timer(Data0),
       case LastResponse of
   	{Seq, _} ->
  -	    NewState = resend_response(State),
  -	    next_state(StateName, NewState);
  +	    NewData = resend_response(Data),
  +	    {keep_state, NewData};
   	{LastSeq, _} when ?SEQ_LE(Seq, LastSeq) ->
   	    %% old request, silently ignore
  -	    next_state(StateName, State);
  +	    {keep_state, Data};
   	_ ->
  -	    {keep_state, State, {next_event, cast, {Msg, Seq, Elements, Header}}}
  +	    {keep_state, Data, {next_event, cast, {Msg, Seq, Elements, Header}}}
       end;
   
  -handle_capwap_message(Header, {Msg, 0, Seq, Elements}, StateName,
  -		      State = #state{request_queue = Queue}) ->
  +handle_capwap_message(Header, {Msg, 0, Seq, Elements},
  +		      Data = #data{request_queue = Queue}) ->
       %% Response
  -    ?log_capwap_control(peer_log_str(State), Msg, Seq, Elements, Header),
  +    ?log_capwap_control(peer_log_str(Data), Msg, Seq, Elements, Header),
       case queue:peek(Queue) of
   	{value, {Seq, _, NotifyFun}} ->
  -	    State1 = ack_request(State),
  -	    State2 = response_notify(NotifyFun, proplists:get_value(result_code, Elements),
  -				     {Msg, Elements, Header}, State1),
  -	    {keep_state, State2, {next_event, cast, {Msg, Seq, Elements, Header}}};
  +	    Data1 = ack_request(Data),
  +	    Data2 = response_notify(NotifyFun, proplists:get_value(result_code, Elements),
  +				     {Msg, Elements, Header}, Data1),
  +	    {keep_state, Data2, {next_event, cast, {Msg, Seq, Elements, Header}}};
   	_ ->
   	    %% invalid Seq, out-of-order packet, silently ignore,
  -	    next_state(StateName, State)
  +	    keep_state_and_data
       end.
   
   maybe_takeover(CommonName) ->
       case capwap_wtp_reg:lookup(CommonName) of
  -        {ok, OldPid} ->
  -            lager:info("take_over: ~p", [OldPid]),
  -            capwap_ac:take_over(OldPid);
  -        _ ->
  -            ok
  -    end.
  -
  -handle_wtp_event(Elements, Header, State = #state{session = Session}) ->
  +	{ok, OldPid} ->
  +	    lager:info("take_over: ~p", [OldPid]),
  +	    capwap_ac:take_over(OldPid);
  +	_ ->
  +	    ok
  +    end.
  +
  +handle_wtp_event(Elements, Header, Data = #data{session = Session}) ->
       SessionOptsList = lists:foldl(fun(Ev, SOptsList) -> handle_wtp_stats_event(Ev, Header, SOptsList) end, [], Elements),
       if length(SessionOptsList) /= 0 ->
   	    ergw_aaa_session:interim_batch(Session, SessionOptsList);
          true -> ok
       end,
  -    lists:foldl(fun(Ev, State0) -> handle_wtp_action_event(Ev, Header, State0) end, State, Elements).
  -
  -handle_wtp_action_event(#delete_station{radio_id = RadioId, mac = MAC}, _Header, State) ->
  +    lists:foldl(fun(Ev, Data0) -> handle_wtp_action_event(Ev, Header, Data0) end, Data, Elements).
  +
  +handle_wtp_action_event(#delete_station{radio_id = RadioId, mac = MAC}, _Header, Data) ->
       case capwap_station_reg:lookup(self(), RadioId, MAC) of
   	{ok, Station} ->
   	    ieee80211_station:delete(Station);
  
positive.code:      | IEs ].
  
  internal_add_wlan(RadioId, WlanId, NotifyFun,
  		  #state{config = #wtp{radios = Radios}} = State)
    when is_integer(RadioId), is_integer(WlanId) ->
      Radio = lists:keyfind(RadioId, #wtp_radio.radio_id, Radios),
      WLAN = lists:keyfind(WlanId, #wtp_wlan_config.wlan_id, Radio#wtp_radio.wlans),
      internal_add_wlan(Radio, WLAN, NotifyFun, State);
  
  internal_add_wlan(#wtp_radio{radio_id = RadioId} = Radio,
  		  #wtp_wlan_config{wlan_id = WlanId,
  				   ssid = SSID,
  				   suppress_ssid = SuppressSSID} = WlanConfig,
  		  NotifyFun,
  		  #state{config = Config} = State0) ->
      WBID = ?CAPWAP_BINDING_802_11,
      Flags = [{frame,'802.3'}],
      Header = #capwap_header{radio_id = RadioId, wb_id = WBID, flags = Flags},
  
      WlanState = init_wlan_state(Radio, WlanId, WlanConfig, State0),
      State = update_wlan_state({RadioId, WlanId}, fun(_W) -> WlanState end, State0),
  
      AddWlan = #ieee_802_11_add_wlan{
  		 radio_id      = RadioId,
  		 wlan_id       = WlanId,
  		 capability    = [ess, short_slot_time],
  		 auth_type     = open_system,
  		 mac_mode      = WlanState#wlan.mac_mode,
  		 tunnel_mode   = WlanState#wlan.tunnel_mode,
  		 suppress_ssid = SuppressSSID,
  		 ssid          = SSID
  		},
      ReqElements0 = [set_wlan_keys(WlanState, AddWlan)],
      ReqElements1 = lists:foldl(capwap_802_11_ie(Radio, WlanState, _, _), ReqElements0,
  			       WlanState#wlan.information_elements),
      ReqElements2 = wlan_cfg_tp_hold_time(Radio, WlanState, Config, ReqElements1),
      ReqElements = add_wlan_keys(WlanState, ReqElements2),
      ResponseNotifyFun = internal_add_wlan_result({RadioId, WlanId}, NotifyFun, _, _, _),
      send_request(Header, ieee_802_11_wlan_configuration_request, ReqElements, ResponseNotifyFun, State);
  
  internal_add_wlan(RadioId, WlanId, NotifyFun, State)
    when RadioId == false orelse WlanId == false ->
      %% the requested Radio/WLan combination might not be configured,
      %% do nothing....
      response_notify(NotifyFun, -1, unconfigured, State).
  
  internal_add_wlan_result(WlanIdent, NotifyFun, Code, Arg, State0)
    when Code == 0 ->
      State = update_wlan_state(WlanIdent,
  			      fun(W0) ->
  				      W = W0#wlan{state = running},
  				      start_group_rekey_timer(W)
  			      end, State0),
      response_notify(NotifyFun, Code, Arg, State);
  
  internal_add_wlan_result(WlanIdent, NotifyFun, Code, Arg, State0) ->
      State = update_wlan_state(WlanIdent,
  			      fun(W) -> W#wlan{state = unconfigured} end, State0),
      response_notify(NotifyFun, Code, Arg, State).
  
  internal_del_wlan(WlanIdent = {RadioId, WlanId}, NotifyFun,
  		  State = #state{data_channel_address = WTPDataChannelAddress}) ->
      capwap_dp:del_wlan(WTPDataChannelAddress, RadioId, WlanId),
      WBID = ?CAPWAP_BINDING_802_11,
      Flags = [{frame,'802.3'}],
      Header = #capwap_header{radio_id = RadioId, wb_id = WBID, flags = Flags},
      ReqElemDel = [#ieee_802_11_delete_wlan{
                       radio_id = RadioId,
                       wlan_id = WlanId}
                   ],
      State0 = send_request(Header, ieee_802_11_wlan_configuration_request, ReqElemDel, NotifyFun, State),
      remove_wlan(WlanIdent, State0).
  
  remove_wlan(WlanIdent, State = #state{wlans = Wlans}) ->
      case get_wlan(WlanIdent, State) of
  	Wlan = #wlan{} ->
  	    stop_group_rekey_timer(Wlan);
  	_ ->
  	    ok
      end,
      LessWlans = lists:keydelete(WlanIdent, #wlan.wlan_identifier, Wlans),
      State#state{wlans = LessWlans}.
  
  radio_rsn_cipher_capabilities(#wtp_radio{supported_cipher_suites = Suites},
  			      #wtp_wlan_config{
  
negative.code: %%% gen_statem callbacks
  %%%===================================================================
  callback_mode() ->
      [handle_event_function, state_enter].
  
  init([WTPControlChannelAddress]) ->
      process_flag(trap_exit, true),
  