   g_status = STATUS_IDLE;
 }
 
+void update_gps() {
+  if (millis() - g_last_get_gps_ms > 10000) {
+    LGPS.getData(&g_gps_info);
+    Serial.println("gps: " + String((char *)g_gps_info.GPGGA));
+    g_last_get_gps_ms = millis();
+    g_need_report = true;
+  }
+}
+
+void handle_report() {
+  if (!g_need_report) {
+    return;
+  }
+
+  StaticJsonBuffer<JSON_BUF_SIZE> json_buf;
+  JsonObject& root = json_buf.createObject();
+  root["lock"] = is_locked();
+  root["gps"] = (char *)g_gps_info.GPGGA;
+
+  String json;
+  root.printTo(json);
+
+  Serial.println("publish: " + json);
+  g_mqtt_client.publish(g_report_topic, json);
+  g_need_report = false;
+}
+
+void unlock() {
+  if (!is_locked()) {
+    Serial.println("not locked now");
+    return;
+  }
+
+  Serial.println("unlocking");
+}
+
+void handle_msg(String &msg) {
+  StaticJsonBuffer<JSON_BUF_SIZE> json_buf;
+  JsonObject& root = json_buf.parseObject(msg);
+  if (!root.success()) {
+    Serial.println("parse json failed");
+    return;
+  }
+
+  String cmd = root["cmd"];
+  if (cmd == "unlock") {
+    unlock();
+  }
+}
+
 /* messageReceived and extMessageReceived must be defined with no 'static', because MQTTClient use them */
-void messageReceived(String topic, String payload, char * bytes, unsigned int length) {
-  Serial.println("message:");
-  Serial.print(topic);
-  Serial.print(" - ");
-  Serial.print(payload);
+void messageReceived(String topic, String payload, char *bytes, unsigned int length) {
+  Serial.println("msg: " + topic + ", " + payload);
+  handle_msg(payload);
 }
 
 void extMessageReceived(EXTED_CMD cmd, int status, String payload, unsigned int length) {
-  Serial.println("ext message:");
-  Serial.print(cmd);
-  Serial.print(" - ");
-  Serial.print(payload);
+  //  Serial.println("ext msg: " + String(cmd) + ", " + payload);
 }
 
 void setup() {

  Serial.println("wait data");
  while (!net_client.available()) {
    Serial.println(".");
    delay(100);
  }

  memset(buf, 0, 256);

    len = (uint16_t)(((uint8_t)buf[1] << 8) | (uint8_t)buf[2]);
    if (len == strlen((char *)(buf + 3))) {
      Serial.println((char *)(&buf[3]));
      StaticJsonBuffer<JSON_BUF_SIZE> json_buf;
      JsonObject& root = json_buf.parseObject((char *)&buf[3]);
      if (!root.success()) {
        Serial.println("parseObject() failed");
        goto exit;
