anchor.diff:  code_change(_OldVsn, State, _Extra) ->
       {ok, State}.
   
  +handle_reconnect(Error, Phase, #state{ping_timer=Timer} = State) ->
  +    maybe_cancel_timer(Timer),
  +    handle_reconnect0(Error, Phase, State#state{mqttc=undefined, ping_timer=undefined}).
  +
  +handle_reconnect0(Error, Phase, #state{phase=OldPhase, last_connect=Last, connect_count=Count} = State) ->
  +    lager:debug("Connector ~w ~w reconnect ~B", [OldPhase, Error, Count]),
  +    case calendar:datetime_to_gregorian_seconds(calendar:universal_time())
  +            - calendar:datetime_to_gregorian_seconds(Last) of
  +        Diff when Diff < 30, Count > 120 ->
  +            % give up after 2 hours
  +            {stop, Error, State};
  +        Diff when Diff < 30, Count > 0 ->
  +            % wait, then wait even longer, but no longer than 30 sec
  +            timer:send_after(erlang:min(Count*5000, 30000), {connect, Phase}),
  +            {noreply, State#state{connect_count=Count+1}};
  +        Diff when Diff < 30, Count == 0 ->
  +            % initially try to reconnect immediately
  +            {noreply, connect(Phase, State#state{connect_count=1})};
  +        true ->
  +            {noreply, connect(Phase, State#state{connect_count=0})}
  +    end.
  +
  +connect(Phase, #state{cargs=CArgs} = State) ->
  +    {ok, C} = connect0(Phase, CArgs),
  +    State#state{phase=Phase, mqttc=C, last_connect=calendar:universal_time()}.
  +
  +connect0(attempt31, CArgs) ->
  +    emqttc:start_link([{proto_ver, 3} | CArgs]);
  +connect0(attempt311, CArgs) ->
  +    emqttc:start_link([{proto_ver, 4} | CArgs]).
   
   handle_connect(#state{subscribe=undefined}=State) ->
       {noreply, State#state{phase=connected}};
  
positive.code: 
  -include("lorawan.hrl").
  
  -record(state, {cargs, phase, mqttc, ping_timer, subscribe, published, consumed}).
  
  start_link(ConnUri, Conn) ->
      gen_server:start_link(?MODULE, [ConnUri, Conn], []).
  
negative.code: handle_cast({publish, Msg, Vars}, State) ->
      handle_publish(Msg, Vars, State).
  
  handle_info({connect, Phase}, State) ->
      {noreply, connect(Phase, State)};
  handle_info(ping, State) ->
      handle_ping(State);
  
  handle_info({mqttc, C, connected}, State=#state{mqttc=C}) ->
      handle_connect(State);
  handle_info({mqttc, C, disconnected}, State=#state{mqttc=C}) ->
      handle_reconnect(disconnected, attempt311, State);
  handle_info({publish, Topic, Payload}, State) ->
      handle_consume(Topic, Payload, State);
  handle_info({'EXIT', C, Error}, State=#state{phase=attempt311, mqttc=C}) ->
      handle_reconnect(Error, attempt31, State);
  handle_info({'EXIT', C, Error}, State=#state{mqttc=C}) ->
      handle_reconnect(Error, attempt311, State);
  handle_info(_Unknown, State) ->
      {noreply, State}.
  
  