source: asp3_tinet_ecnl_rx/trunk/app1_usb_watt_meter/src/client.c@ 342

Last change on this file since 342 was 342, checked in by coas-nagasima, 5 years ago

syscallが関数呼びになるよう変更
他更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 10.1 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2016 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id$
36 */
37#include <lib/curl_config.h>
38#include <lib/curl_setup.h>
39#include <curl/curl.h>
40#include <wolfssl/wolfcrypt/wc_port.h>
41//#include <wolfssl/ssl.h>
42//#include <sys/socket.h>
43#include <string.h>
44#include <kernel.h>
45#include <t_syslog.h>
46#include "echonet_main.h"
47#include "kernel_cfg.h"
48#include "ff.h"
49
50#define SKIP_PEER_VERIFICATION
51//#define SKIP_HOSTNAME_VERIFICATION
52char response[80];
53
54void client_init(void)
55{
56 //uITRON4_minit(ITRON_POOL_SIZE);
57
58 curl_global_init(CURL_GLOBAL_DEFAULT);
59}
60
61size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
62{
63 int rest = size * nmemb;
64 int len;
65
66 while (rest > 0) {
67 len = rest;
68 if (len > (sizeof(response) - 1)) {
69 len = sizeof(response) - 1;
70 }
71
72 memcpy(response, buffer, len);
73
74 response[len] = '\0';
75
76 syslog(LOG_NOTICE, response);
77
78 dly_tsk(100 * 1000);
79
80 rest -= len;
81 buffer = (char *)buffer + len;
82 }
83
84 return size * nmemb;
85}
86
87size_t read_data(char *buffer, size_t size, size_t nitems, void *instream)
88{
89 FIL *file = (FIL *)instream;
90 UINT ret = 0;
91 FRESULT res;
92
93 res = f_read(file, buffer, size * nitems, &ret);
94 if (res != FR_OK)
95 return 0;
96
97 int rest = ret;
98 int len;
99
100 while (rest > 0) {
101 len = rest;
102 if (len > (sizeof(response) - 1)) {
103 len = sizeof(response) - 1;
104 }
105
106 memcpy(response, buffer, len);
107
108 response[len] = '\0';
109
110 syslog(LOG_NOTICE, response);
111
112 dly_tsk(100);
113
114 rest -= len;
115 buffer = (char *)buffer + len;
116 }
117
118 return ret;
119}
120
121char errbuf[CURL_ERROR_SIZE];
122
123static void get_logfname(char *fname)
124{
125 // fname = "0:/log/2016010100000000.log"
126 time_t t;
127 struct tm tm;
128 int tmp1, tmp2;
129 char *pos = &fname[7];
130
131 time(&t);
132 gmtime_r(&t, &tm);
133
134 /* 年 */
135 tmp1 = 1900 + tm.tm_year;
136 tmp2 = tmp1 / 1000;
137 tmp1 -= tmp2 * 1000;
138 *pos++ = '0' + tmp2;
139 tmp2 = tmp1 / 100;
140 tmp1 -= tmp2 * 100;
141 *pos++ = '0' + tmp2;
142 tmp2 = tmp1 / 10;
143 tmp1 -= tmp2 * 10;
144 *pos++ = '0' + tmp2;
145 *pos++ = '0' + tmp1;
146 /* 月 */
147 tmp1 = tm.tm_mon + 1;
148 tmp2 = tmp1 / 10;
149 tmp1 -= tmp2 * 10;
150 *pos++ = '0' + tmp2;
151 *pos++ = '0' + tmp1;
152 /* 日 */
153 tmp1 = tm.tm_mday;
154 tmp2 = tmp1 / 10;
155 tmp1 -= tmp2 * 10;
156 *pos++ = '0' + tmp2;
157 *pos++ = '0' + tmp1;
158 /* 時 */
159 tmp1 = tm.tm_hour;
160 tmp2 = tmp1 / 10;
161 tmp1 -= tmp2 * 10;
162 *pos++ = '0' + tmp2;
163 *pos++ = '0' + tmp1;
164 /* 分 */
165 tmp1 = tm.tm_min;
166 tmp2 = tmp1 / 10;
167 tmp1 -= tmp2 * 10;
168 *pos++ = '0' + tmp2;
169 *pos++ = '0' + tmp1;
170 /* 秒 */
171 tmp1 = tm.tm_sec;
172 tmp2 = tmp1 / 10;
173 tmp1 -= tmp2 * 10;
174 *pos++ = '0' + tmp2;
175 *pos++ = '0' + tmp1;
176}
177
178static FRESULT write_log(char *fname)
179{
180 FIL file;
181 FRESULT ret;
182
183 ret = f_open(&file, fname, FA_CREATE_ALWAYS | FA_WRITE);
184 if (ret != FR_OK) {
185 syslog(LOG_ERROR, "not open a upload file %d", ret);
186 return ret;
187 }
188
189 f_printf(&file, "{\"datetime\":\"");
190 for (int i = 7; i < 21; i++)
191 f_putc(fname[i], &file);
192 f_printf(&file, "\",");
193
194 for (int i = 0; i < 6; i++) {
195 struct watt_hour_meter_t *meter = &electric_energy_meter_data[i];
196 uint32_t *log;
197 int len;
198
199 f_printf(&file, "\"channel%d\":[", i + 1);
200
201 wai_sem(MAIN_SEMAPHORE);
202
203 len = 48 - meter->current_pos;
204 if (len > 0) {
205 log = &meter->integral_electric_energy_measurement_log[meter->current_pos];
206 for (int j = 1; j < len; j++) {
207 f_printf(&file, "%d,", *log);
208 }
209 f_printf(&file, "%d", *log);
210 }
211 len = 48 - len;
212 if (len > 0) {
213 f_putc(',', &file);
214
215 log = &meter->integral_electric_energy_measurement_log[0];
216 for (int j = 1; j < len; j++) {
217 f_printf(&file, "%d,", *log);
218 }
219 f_printf(&file, "%d", *log);
220 }
221
222 sig_sem(MAIN_SEMAPHORE);
223
224 f_putc(']', &file);
225 if (i != 5) {
226 f_putc(',', &file);
227 }
228 }
229
230 f_putc('}', &file);
231
232file_close:
233 f_close(&file);
234
235 return FR_OK;
236}
237
238void client_task(intptr_t exinf)
239{
240 CURL *curl;
241 CURLcode res;
242 int error = 0;
243 //const char *data = "{\"value\":\"data post\"}";
244 struct curl_slist *list = NULL;
245 FIL file;
246 FRESULT ret;
247 char fname[] = {"1:/log/20160101000000.log"};
248
249 get_logfname(fname);
250
251 ret = write_log(fname);
252 if (ret != FR_OK) {
253 syslog(LOG_ERROR, "log file write error %d", ret);
254 return;
255 }
256
257 ret = f_open(&file, fname, FA_READ);
258 if (ret != FR_OK) {
259 syslog(LOG_ERROR, "log file open error %d", ret);
260 return;
261 }
262
263 syslog(LOG_NOTICE, "cURL start");
264
265 curl = curl_easy_init();
266 if (curl == NULL) {
267 syslog(LOG_ERROR, "curl_easy_init() failed\n");
268 goto file_close;
269 }
270
271 /* ask libcurl to show us the verbose output */
272 curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
273
274 res = curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
275 if (res != CURLE_OK)
276 syslog(LOG_ERROR, "CURLOPT_URL failed: %s\n",
277 curl_easy_strerror(res));
278
279 /* set the error buffer as empty before performing a request */
280 errbuf[0] = 0;
281
282 /* provide a buffer to store errors in */
283 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
284
285#ifdef SKIP_PEER_VERIFICATION
286 /*
287 * If you want to connect to a site who isn't using a certificate that is
288 * signed by one of the certs in the CA bundle you have, you can skip the
289 * verification of the server's certificate. This makes the connection
290 * A LOT LESS SECURE.
291 *
292 * If you have a CA cert for the server stored someplace else than in the
293 * default bundle, then the CURLOPT_CAPATH option might come handy for
294 * you.
295 */
296 res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
297 if (res != CURLE_OK)
298 syslog(LOG_ERROR, "CURLOPT_SSL_VERIFYPEER failed: %s\n",
299 curl_easy_strerror(res));
300#else
301 res = curl_easy_setopt(curl, CURLOPT_CAINFO, "0:/certs/ca-cert.pem");
302 if (res != CURLE_OK)
303 syslog(LOG_ERROR, "CURLOPT_CAINFO failed: %s\n",
304 curl_easy_strerror(res));
305
306 res = curl_easy_setopt(curl, CURLOPT_SSLCERT, "0:/certs/client-cert.pem");
307 if (res != CURLE_OK)
308 syslog(LOG_ERROR, "CURLOPT_SSLCERT failed: %s\n",
309 curl_easy_strerror(res));
310
311 res = curl_easy_setopt(curl, CURLOPT_SSLKEY, "0:/certs/client-key.pem");
312 if (res != CURLE_OK)
313 syslog(LOG_ERROR, "CURLOPT_SSLKEY failed: %s\n",
314 curl_easy_strerror(res));
315#endif
316
317#ifdef SKIP_HOSTNAME_VERIFICATION
318 /*
319 * If the site you're connecting to uses a different host name that what
320 * they have mentioned in their server certificate's commonName (or
321 * subjectAltName) fields, libcurl will refuse to connect. You can skip
322 * this check, but this will make the connection less secure.
323 */
324 res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
325 if (res != CURLE_OK)
326 syslog(LOG_ERROR, "CURLOPT_SSL_VERIFYHOST failed: %s\n",
327 curl_easy_strerror(res));
328#endif
329
330 /*res = curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy.example.com:8080");
331 if (res != CURLE_OK)
332 syslog(LOG_ERROR, "CURLOPT_PROXY failed: %s\n",
333 curl_easy_strerror(res));*/
334
335 curl_easy_setopt(curl, CURLOPT_POST, 1);
336
337 /* size of the POST data */
338 //curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(data));
339 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, file.fsize);
340
341 /* pass in a pointer to the data - libcurl will not copy */
342 //curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
343
344 list = curl_slist_append(list, "Content-Type: application/json");
345
346 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
347
348 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&error);
349
350 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
351
352 /* now specify which file to upload */
353 curl_easy_setopt(curl, CURLOPT_READDATA, &file);
354
355 /* we want to use our own read function */
356 curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_data);
357
358 syslog(LOG_NOTICE, "cURL perform the request");
359 tslp_tsk(100 * 1000);
360
361 /* Perform the request, res will get the return code */
362 res = curl_easy_perform(curl);
363 /* Check for errors */
364 if (res != CURLE_OK) {
365 syslog(LOG_ERROR, "curl_easy_perform() failed: %s\n",
366 curl_easy_strerror(res));
367 syslog(LOG_ERROR, errbuf);
368 }
369
370 /* always cleanup */
371 curl_easy_cleanup(curl);
372
373 syslog(LOG_NOTICE, "cURL end");
374
375file_close:
376 f_close(&file);
377}
378
379void client_fin(void)
380{
381 curl_global_cleanup();
382}
Note: See TracBrowser for help on using the repository browser.