anchor.diff:  
   -include("lorawan.hrl").
   
  --record(state, {cargs, phase, mqttc, ping_timer, subscribe, published, consumed}).
  +-record(state, {cargs, phase, mqttc, last_connect, connect_count,
  +    ping_timer, subscribe, published, consumed}).
   
   start_link(ConnUri, Conn) ->
       gen_server:start_link(?MODULE, [ConnUri, Conn], []).
  
positive.code: handle_cast({publish, Msg, Vars}, State) ->
      handle_publish(Msg, Vars, State).
  
  handle_info({mqttc, C, connected}, State=#state{mqttc=C}) ->
      handle_connect(State);
  handle_info({mqttc, C, disconnected}, State=#state{mqttc=C}) ->
      handle_disconnect(State);
  handle_info(ping, State) ->
      handle_ping(State);
  handle_info({publish, Topic, Payload}, State) ->
      handle_consume(Topic, Payload, State);
  handle_info({'EXIT', C, {shutdown, _Error}}, State=#state{cargs=CArgs, phase=connect311, mqttc=C}) ->
      % downgrade to MQTT 3.1
      {ok, C2} = emqttc:start_link([{proto_ver, 3} | CArgs]),
      {noreply, State#state{phase=connect31, mqttc=C2}};
  handle_info({'EXIT', C, Error}, State=#state{mqttc=C}) ->
      {stop, Error, State};
  handle_info(_Unknown, State) ->
      {noreply, State}.
  
  
negative.code:     Timer = schedule_refresh(),
      {noreply, State#state{phase=connected, ping_timer=Timer}}.
  
  handle_ping(State=#state{mqttc=undefined}) ->
      % ping timer expired, but meanwhile the client crashed
      % wait for reconnection
      {noreply, State};
  handle_ping(State=#state{mqttc=C}) ->
      pong = emqttc:ping(C),
      Timer = schedule_refresh(),
      {noreply, State#state{ping_timer=Timer}}.
  
  schedule_refresh() ->
      erlang:send_after(60*1000, self(), ping).
  