Index: asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/client.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/client.c	(revision 370)
+++ asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/client.c	(revision 371)
@@ -33,5 +33,5 @@
  *  の責任を負わない．
  *
- *  @(#) $Id$
+ *  @(#) $Id: client.c 1729 2019-01-09 14:44:36Z coas-nagasima $
  */
 #include <lib/curl_config.h>
@@ -62,4 +62,5 @@
 google_drive_t google_drive;
 
+int read_client_info(google_drive_t *gd, const char *fname);
 void curl_setopt_common(CURL *curl);
 int google_drive_error_callback(jsonsl_t jsn, jsonsl_error_t err,
@@ -71,10 +72,134 @@
 {
 	google_drive_t *gd = &google_drive;
-	jsonsl_t jsn;
 
 	memset(gd, 0, sizeof(google_drive_t));
 	memcpy(gd->fname, "1:/log/20160101000000.log", sizeof(gd->fname));
 
-	jsn = gd->jsn = jsonsl_new(3);
+	read_client_info(gd, "1:/client_secret.json");
+
+	curl_global_init(CURL_GLOBAL_DEFAULT);
+}
+
+size_t write_callback(void *buffer, size_t size, size_t nmemb, void *arg)
+{
+	google_drive_t *gd = (google_drive_t *)arg;
+	jsonsl_t jsn = gd->jsn;
+	size_t len = size * nmemb, pos;
+	jsonsl_char_t data;
+
+	for (pos = 0; pos < len; pos++) {
+		data = *((jsonsl_char_t *)&((uint8_t *)buffer)[pos]);
+
+		if ((gd->jsn_buf_pos >= 0) && (gd->jsn_buf_pos < sizeof(gd->jsn_buf)))
+			gd->jsn_buf[gd->jsn_buf_pos++] = data;
+		jsonsl_feed(jsn, &data, 1);
+	}
+
+	return len;
+}
+
+void client_info_state_start(google_drive_t *gd, struct jsonsl_state_st *state, const char *buf)
+{
+	switch (gd->state) {
+	case psRoot:
+		if (state->level != 2) {
+			break;
+		}
+		else if (strcmp(buf, "installed") == 0) {
+			gd->state = psInstalled;
+		}
+		break;
+	case psInstalled:
+		if (state->level == 2) {
+			gd->state = psRoot;
+			break;
+		}
+		if (state->level != 3) {
+			break;
+		}
+		else if (strcmp(buf, "client_id") == 0) {
+			gd->state = psClientId;
+		}
+		else if (strcmp(buf, "project_id") == 0) {
+			gd->state = psProjectId;
+		}
+		else if (strcmp(buf, "auth_uri") == 0) {
+			gd->state = psAuthUri;
+		}
+		else if (strcmp(buf, "token_uri") == 0) {
+			gd->state = psTokenUri;
+		}
+		else if (strcmp(buf, "auth_provider_x509_cert_url") == 0) {
+			gd->state = psAuthProviderX509CertUrl;
+		}
+		else if (strcmp(buf, "client_secret") == 0) {
+			gd->state = psClientSecret;
+		}
+		else if (strcmp(buf, "redirect_uris") == 0) {
+			gd->state = psRedirectUris;
+			gd->index = 0;
+		}
+		break;
+	case psClientId:
+		if (state->type == JSONSL_T_STRING) {
+			strlcpy(gd->client_info.client_id, buf, sizeof(gd->client_info.client_id));
+			gd->state = psInstalled;
+		}
+		break;
+	case psProjectId:
+		if (state->type == JSONSL_T_STRING) {
+			strlcpy(gd->client_info.project_id, buf, sizeof(gd->client_info.project_id));
+			gd->state = psInstalled;
+		}
+		break;
+	case psAuthUri:
+		if (state->type == JSONSL_T_STRING) {
+			strlcpy(gd->client_info.auth_uri, buf, sizeof(gd->client_info.auth_uri));
+			gd->state = psInstalled;
+		}
+		break;
+	case psTokenUri:
+		if (state->type == JSONSL_T_STRING) {
+			strlcpy(gd->client_info.token_uri, buf, sizeof(gd->client_info.token_uri));
+			gd->state = psInstalled;
+		}
+		break;
+	case psAuthProviderX509CertUrl:
+		if (state->type == JSONSL_T_STRING) {
+			strlcpy(gd->client_info.auth_provider_x509_cert_url, buf, sizeof(gd->client_info.auth_provider_x509_cert_url));
+			gd->state = psInstalled;
+		}
+		break;
+	case psClientSecret:
+		if (state->type == JSONSL_T_STRING) {
+			strlcpy(gd->client_info.client_secret, buf, sizeof(gd->client_info.client_secret));
+			gd->state = psInstalled;
+		}
+		break;
+	case psRedirectUris:
+		if (state->type == JSONSL_T_STRING) {
+			strlcpy(gd->client_info.redirect_uris[gd->index], buf, sizeof(gd->client_info.redirect_uris[0]));
+			gd->index++;
+			if (gd->index == 2) {
+				gd->state = psInstalled;
+			}
+		}
+		break;
+	}
+}
+
+void client_info_state_end(google_drive_t *gd, struct jsonsl_state_st *state, const char *buf)
+{
+}
+
+int read_client_info(google_drive_t *gd, const char *fname)
+{
+	FIL file;
+	FRESULT ret;
+	jsonsl_t jsn = gd->jsn = jsonsl_new(5);
+	char buffer[16];
+	size_t len, pos;
+	jsonsl_char_t data;
+
 	jsn->data = gd;
 	jsn->error_callback = google_drive_error_callback;
@@ -82,25 +207,39 @@
 	jsonsl_enable_all_callbacks(jsn);
 
-	//uITRON4_minit(ITRON_POOL_SIZE);
-
-	curl_global_init(CURL_GLOBAL_DEFAULT);
-}
-
-size_t write_callback(void *buffer, size_t size, size_t nmemb, void *arg)
-{
-	google_drive_t *gd = (google_drive_t *)arg;
-	jsonsl_t jsn = gd->jsn;
-	size_t len = size * nmemb, pos;
-	jsonsl_char_t data;
-
-	for (pos = 0; pos < len; pos++) {
-		data = *((jsonsl_char_t *)&((uint8_t *)buffer)[pos]);
-
-		if ((gd->jsn_buf_pos >= 0) && (gd->jsn_buf_pos < sizeof(gd->jsn_buf)))
-			gd->jsn_buf[gd->jsn_buf_pos++] = data;
-		jsonsl_feed(jsn, &data, 1);
-	}
-
-	return len;
+	gd->jsn_buf_pos = -1;
+	gd->start = client_info_state_start;
+	gd->end = client_info_state_end;
+	gd->state = psRoot;
+
+	ret = f_open(&file, fname, FA_READ);
+	if (ret != FR_OK) {
+		printf("not open %s file %d\n", fname, ret);
+		ret = -1;
+		goto error;
+	}
+
+	for (;;) {
+		len = 0;
+		ret = f_read(&file, buffer, sizeof(buffer), &len);
+		if ((ret != FR_OK) || (len <= 0))
+			break;
+
+		for (pos = 0; pos < len; pos++) {
+			data = *((jsonsl_char_t *)&((uint8_t *)buffer)[pos]);
+
+			if ((gd->jsn_buf_pos >= 0) && (gd->jsn_buf_pos < sizeof(gd->jsn_buf)))
+				gd->jsn_buf[gd->jsn_buf_pos++] = data;
+			jsonsl_feed(jsn, &data, 1);
+		}
+	}
+
+	f_close(&file);
+
+	ret = 0;
+error:
+	gd->jsn = NULL;
+	jsonsl_destroy(jsn);
+
+	return ret;
 }
 
@@ -192,5 +331,4 @@
 	size_t len;
 	char *postdata;
-	jsonsl_t jsn = gd->jsn;
 
 	len = strnlen(client_info->client_id, sizeof(client_info->client_id));
@@ -198,9 +336,14 @@
 		return -1;
 
+	jsonsl_t jsn = gd->jsn = jsonsl_new(3);
+	jsn->data = gd;
+	jsn->error_callback = google_drive_error_callback;
+	jsn->action_callback = google_drive_state_callback;
+	jsonsl_enable_all_callbacks(jsn);
+
 	gd->jsn_buf_pos = -1;
-
-	jsonsl_reset(jsn);
 	gd->start = get_device_id_state_start;
 	gd->end = get_device_id_state_end;
+	gd->state = psRoot;
 
 	slist1 = NULL;
@@ -236,4 +379,7 @@
 	curl_slist_free_all(slist1);
 	slist1 = NULL;
+
+	gd->jsn = NULL;
+	jsonsl_destroy(jsn);
 
 	return (int)ret;
@@ -327,5 +473,4 @@
 	size_t len;
 	char *postdata;
-	jsonsl_t jsn = gd->jsn;
 
 	len = strlen(credential->device_code);
@@ -333,9 +478,14 @@
 		return -1;
 
+	jsonsl_t jsn = gd->jsn = jsonsl_new(3);
+	jsn->data = gd;
+	jsn->error_callback = google_drive_error_callback;
+	jsn->action_callback = google_drive_state_callback;
+	jsonsl_enable_all_callbacks(jsn);
+
 	gd->jsn_buf_pos = -1;
-
-	jsonsl_reset(jsn);
 	gd->start = get_access_token_state_start;
 	gd->end = get_access_token_state_end;
+	gd->state = psRoot;
 
 	slist1 = NULL;
@@ -375,4 +525,7 @@
 	curl_slist_free_all(slist1);
 	slist1 = NULL;
+
+	gd->jsn = NULL;
+	jsonsl_destroy(jsn);
 
 	return (int)ret;
@@ -457,5 +610,4 @@
 	size_t len;
 	char *postdata;
-	jsonsl_t jsn = gd->jsn;
 
 	len = strlen(credential->refresh_token);
@@ -463,9 +615,14 @@
 		return -1;
 
+	jsonsl_t jsn = gd->jsn = jsonsl_new(3);
+	jsn->data = gd;
+	jsn->error_callback = google_drive_error_callback;
+	jsn->action_callback = google_drive_state_callback;
+	jsonsl_enable_all_callbacks(jsn);
+
 	gd->jsn_buf_pos = -1;
-
-	jsonsl_reset(jsn);
 	gd->start = update_access_token_state_start;
 	gd->end = update_access_token_state_end;
+	gd->state = psRoot;
 
 	slist1 = NULL;
@@ -504,4 +661,7 @@
 	curl_slist_free_all(slist1);
 	slist1 = NULL;
+
+	gd->jsn = NULL;
+	jsonsl_destroy(jsn);
 
 	return (int)ret;
@@ -525,5 +685,4 @@
 	struct curl_slist *slist1;
 	char *postdata;
-	jsonsl_t jsn = gd->jsn;
 
 	len = strlen(credential->access_token);
@@ -531,9 +690,14 @@
 		return -1;
 
+	jsonsl_t jsn = gd->jsn = jsonsl_new(3);
+	jsn->data = gd;
+	jsn->error_callback = google_drive_error_callback;
+	jsn->action_callback = google_drive_state_callback;
+	jsonsl_enable_all_callbacks(jsn);
+
 	gd->jsn_buf_pos = -1;
-
-	jsonsl_reset(jsn);
 	gd->start = revoke_device_state_start;
 	gd->end = revoke_device_state_end;
+	gd->state = psRoot;
 
 	slist1 = NULL;
@@ -563,4 +727,9 @@
 	curl_slist_free_all(slist1);
 	slist1 = NULL;
+
+	gd->jsn = NULL;
+	jsonsl_destroy(jsn);
+
+	memset(credential, 0, sizeof(*credential));
 
 	return (int)ret;
@@ -707,18 +876,27 @@
 	char *postdata, *authorization;
 	static const char buf[] = "Expect:";
-	jsonsl_t jsn = gd->jsn;
 	FIL file;
 	FRESULT fret;
 
+	len = strnlen(gd->credential.access_token, sizeof(gd->credential.access_token));
+	if (len <= 0)
+		return -1;
+
+	jsonsl_t jsn = gd->jsn = jsonsl_new(3);
+	jsn->data = gd;
+	jsn->error_callback = google_drive_error_callback;
+	jsn->action_callback = google_drive_state_callback;
+	jsonsl_enable_all_callbacks(jsn);
+
 	gd->jsn_buf_pos = -1;
-
-	jsonsl_reset(jsn);
 	gd->start = upload_file_state_start;
 	gd->end = upload_file_state_end;
+	gd->state = psRoot;
 
 	fret = f_open(&file, localfilepath, FA_READ);
 	if (fret != FR_OK) {
 		printf("log file open error %d\n", fret);
-		return -1;
+		ret = -1;
+		goto error;
 	}
 
@@ -770,4 +948,8 @@
 
 	f_close(&file);
+
+error:
+	gd->jsn = NULL;
+	jsonsl_destroy(jsn);
 
 	return (int)ret;
@@ -1133,8 +1315,4 @@
 void client_final(void)
 {
-	google_drive_t *gd = &google_drive;
-	jsonsl_t jsn = gd->jsn;
-
 	curl_global_cleanup();
-	jsonsl_destroy(jsn);
-}
+}
Index: asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/client.h
===================================================================
--- asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/client.h	(revision 370)
+++ asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/client.h	(revision 371)
@@ -33,5 +33,5 @@
  *  の責任を負わない．
  * 
- *  @(#) $Id$
+ *  @(#) $Id: client.h 1784 2019-02-06 01:11:25Z coas-nagasima $
  */
 
@@ -41,5 +41,10 @@
 typedef struct client_info_t {
 	char client_id[80];
+	char project_id[32];
+	char auth_uri[64];
+	char token_uri[48];
+	char auth_provider_x509_cert_url[48];
 	char client_secret[32];
+	char redirect_uris[2][32];
 } client_info_t;
 
@@ -70,4 +75,12 @@
 typedef enum google_drive_parse_state_t {
 	psRoot,
+	psInstalled,
+	psClientId,
+	psProjectId,
+	psAuthUri,
+	psTokenUri,
+	psAuthProviderX509CertUrl,
+	psClientSecret,
+	psRedirectUris,
 	psDeviceCode,
 	psUserCode,
@@ -99,4 +112,5 @@
 	jsonsl_t jsn;
 	google_drive_parse_state_t state;
+	int index;
 	char fname[sizeof("1:/log/20160101000000.log")];
 	char jsn_buf[256];
Index: asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/main.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/main.c	(revision 370)
+++ asp3_tinet_ecnl_arm/trunk/app1_usb_watt_meter/src/main.c	(revision 371)
@@ -242,11 +242,11 @@
 	}
 
+	ether_set_link_callback(netif_link_callback);
+
+	/* 初期化 */
+	ffarch_init();
+
 	/* libcurlとWolfSSLの初期化 */
 	client_init();
-
-	ether_set_link_callback(netif_link_callback);
-
-	/* 初期化 */
-	ffarch_init();
 
 	gpio_write(&led_green, 0);
