source: UsbWattMeter/trunk/src/usb_watt_meter/client.c

Last change on this file was 167, checked in by coas-nagasima, 6 years ago

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 9.3 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: client.c 167 2016-03-08 11:37:45Z coas-nagasima $
36 */
37#include <lib/curl_setup.h>
38#include <curl/curl.h>
39#include <wolfssl/wolfcrypt/wc_port.h>
40#include <wolfssl/ssl.h>
41#include <lwip/sockets.h>
42#include <string.h>
43#include "main.h"
44#include "kernel_cfg.h"
45#include "ff.h"
46
47#define SKIP_PEER_VERIFICATION
48//#define SKIP_HOSTNAME_VERIFICATION
49char response[80];
50
51void client_init(void)
52{
53 uITRON4_minit(ITRON_POOL_SIZE);
54
55 curl_global_init(CURL_GLOBAL_DEFAULT);
56}
57
58size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
59{
60 int rest = size * nmemb;
61 int len;
62
63 while (rest > 0) {
64 len = rest;
65 if (len > (sizeof(response) - 1)) {
66 len = sizeof(response) - 1;
67 }
68
69 memcpy(response, buffer, len);
70
71 response[len] = '\0';
72
73 syslog(LOG_NOTICE, response);
74
75 dly_tsk(100);
76
77 rest -= len;
78 (char *)buffer += len;
79 }
80
81 return size * nmemb;
82}
83
84size_t read_data(char *buffer, size_t size, size_t nitems, void *instream)
85{
86 FIL *file = (FIL *)instream;
87 UINT ret = 0;
88 FRESULT res;
89
90 res = f_read(file, buffer, size * nitems, &ret);
91 if (res != FR_OK)
92 return 0;
93
94 int rest = ret;
95 int len;
96
97 while (rest > 0) {
98 len = rest;
99 if (len > (sizeof(response) - 1)) {
100 len = sizeof(response) - 1;
101 }
102
103 memcpy(response, buffer, len);
104
105 response[len] = '\0';
106
107 syslog(LOG_NOTICE, response);
108
109 dly_tsk(100);
110
111 rest -= len;
112 (char *)buffer += len;
113 }
114
115 return ret;
116}
117
118char errbuf[CURL_ERROR_SIZE];
119
120static void get_logfname(char *fname)
121{
122 // fname = "0:/log/2016010100000000.log"
123 time_t t;
124 struct tm tm;
125 int tmp1, tmp2;
126 char *pos = &fname[7];
127
128 sys_time(&t);
129 gmtime_r(&t, &tm);
130
131 /* 年 */
132 tmp1 = 1900 + tm.tm_year;
133 tmp2 = tmp1 / 1000;
134 tmp1 -= tmp2 * 1000;
135 *pos++ = '0' + tmp2;
136 tmp2 = tmp1 / 100;
137 tmp1 -= tmp2 * 100;
138 *pos++ = '0' + tmp2;
139 tmp2 = tmp1 / 10;
140 tmp1 -= tmp2 * 10;
141 *pos++ = '0' + tmp2;
142 *pos++ = '0' + tmp1;
143 /* 月 */
144 tmp1 = tm.tm_mon + 1;
145 tmp2 = tmp1 / 10;
146 tmp1 -= tmp2 * 10;
147 *pos++ = '0' + tmp2;
148 *pos++ = '0' + tmp1;
149 /* 日 */
150 tmp1 = tm.tm_mday;
151 tmp2 = tmp1 / 10;
152 tmp1 -= tmp2 * 10;
153 *pos++ = '0' + tmp2;
154 *pos++ = '0' + tmp1;
155 /* 時 */
156 tmp1 = tm.tm_hour;
157 tmp2 = tmp1 / 10;
158 tmp1 -= tmp2 * 10;
159 *pos++ = '0' + tmp2;
160 *pos++ = '0' + tmp1;
161 /* 分 */
162 tmp1 = tm.tm_min;
163 tmp2 = tmp1 / 10;
164 tmp1 -= tmp2 * 10;
165 *pos++ = '0' + tmp2;
166 *pos++ = '0' + tmp1;
167 /* 秒 */
168 tmp1 = tm.tm_sec;
169 tmp2 = tmp1 / 10;
170 tmp1 -= tmp2 * 10;
171 *pos++ = '0' + tmp2;
172 *pos++ = '0' + tmp1;
173}
174
175static FRESULT write_log(char *fname)
176{
177 FIL file;
178 FRESULT ret;
179
180 ret = f_open(&file, fname, FA_CREATE_ALWAYS | FA_WRITE);
181 if (ret != FR_OK) {
182 syslog(LOG_ERROR, "not open a upload file %d", ret);
183 return ret;
184 }
185
186 f_printf(&file, "{\"datetime\":\"");
187 for (int i = 7; i < 21; i++)
188 f_putc(fname[i], &file);
189 f_printf(&file, "\",");
190
191 for (int i = 0; i < 6; i++) {
192 struct watt_hour_meter_t *meter = &electric_energy_meter_data[i];
193 uint32_t *log;
194 int len;
195
196 f_printf(&file, "\"channel%d\":[", i + 1);
197
198 wai_sem(MAIN_SEMAPHORE);
199
200 len = 48 - meter->current_pos;
201 if (len > 0) {
202 log = &meter->integral_electric_energy_measurement_log[meter->current_pos];
203 for (int j = 1; j < len; j++) {
204 f_printf(&file, "%d,", *log);
205 }
206 f_printf(&file, "%d", *log);
207 }
208 len = 48 - len;
209 if (len > 0) {
210 f_putc(',', &file);
211
212 log = &meter->integral_electric_energy_measurement_log[0];
213 for (int j = 1; j < len; j++) {
214 f_printf(&file, "%d,", *log);
215 }
216 f_printf(&file, "%d", *log);
217 }
218
219 sig_sem(MAIN_SEMAPHORE);
220
221 f_putc(']', &file);
222 if (i != 5) {
223 f_putc(',', &file);
224 }
225 }
226
227 f_putc('}', &file);
228
229file_close:
230 f_close(&file);
231
232 return FR_OK;
233}
234
235void client_task(intptr_t exinf)
236{
237 CURL *curl;
238 CURLcode res;
239 int error = 0;
240 //const char *data = "{\"value\":\"data post\"}";
241 struct curl_slist *list = NULL;
242 FIL file;
243 FRESULT ret;
244 char fname[] = {"0:/log/20160101000000.log"};
245
246 get_logfname(fname);
247
248 ret = write_log(fname);
249 if (ret != FR_OK) {
250 syslog(LOG_ERROR, "log file write error %d", ret);
251 return;
252 }
253
254 ret = f_open(&file, fname, FA_READ);
255 if (ret != FR_OK) {
256 syslog(LOG_ERROR, "log file open error %d", ret);
257 return;
258 }
259
260 syslog(LOG_NOTICE, "cURL start");
261
262 curl = curl_easy_init();
263 if (curl == NULL) {
264 syslog(LOG_ERROR, "curl_easy_init() failed\n");
265 goto file_close;
266 }
267
268 /* ask libcurl to show us the verbose output */
269 curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
270
271 res = curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
272 if (res != CURLE_OK)
273 syslog(LOG_ERROR, "CURLOPT_URL failed: %s\n",
274 curl_easy_strerror(res));
275
276 /* set the error buffer as empty before performing a request */
277 errbuf[0] = 0;
278
279 /* provide a buffer to store errors in */
280 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
281
282#ifdef SKIP_PEER_VERIFICATION
283 /*
284 * If you want to connect to a site who isn't using a certificate that is
285 * signed by one of the certs in the CA bundle you have, you can skip the
286 * verification of the server's certificate. This makes the connection
287 * A LOT LESS SECURE.
288 *
289 * If you have a CA cert for the server stored someplace else than in the
290 * default bundle, then the CURLOPT_CAPATH option might come handy for
291 * you.
292 */
293 res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
294 if (res != CURLE_OK)
295 syslog(LOG_ERROR, "CURLOPT_SSL_VERIFYPEER failed: %s\n",
296 curl_easy_strerror(res));
297#else
298 res = curl_easy_setopt(curl, CURLOPT_CAINFO, "0:/certs/ca-cert.pem");
299 if (res != CURLE_OK)
300 syslog(LOG_ERROR, "CURLOPT_CAINFO failed: %s\n",
301 curl_easy_strerror(res));
302
303 res = curl_easy_setopt(curl, CURLOPT_SSLCERT, "0:/certs/client-cert.pem");
304 if (res != CURLE_OK)
305 syslog(LOG_ERROR, "CURLOPT_SSLCERT failed: %s\n",
306 curl_easy_strerror(res));
307
308 res = curl_easy_setopt(curl, CURLOPT_SSLKEY, "0:/certs/client-key.pem");
309 if (res != CURLE_OK)
310 syslog(LOG_ERROR, "CURLOPT_SSLKEY failed: %s\n",
311 curl_easy_strerror(res));
312#endif
313
314#ifdef SKIP_HOSTNAME_VERIFICATION
315 /*
316 * If the site you're connecting to uses a different host name that what
317 * they have mentioned in their server certificate's commonName (or
318 * subjectAltName) fields, libcurl will refuse to connect. You can skip
319 * this check, but this will make the connection less secure.
320 */
321 res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
322 if (res != CURLE_OK)
323 syslog(LOG_ERROR, "CURLOPT_SSL_VERIFYHOST failed: %s\n",
324 curl_easy_strerror(res));
325#endif
326
327 /*res = curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy.example.com:8080");
328 if (res != CURLE_OK)
329 syslog(LOG_ERROR, "CURLOPT_PROXY failed: %s\n",
330 curl_easy_strerror(res));*/
331
332 curl_easy_setopt(curl, CURLOPT_POST, 1);
333
334 /* size of the POST data */
335 //curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(data));
336 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, file.fsize);
337
338 /* pass in a pointer to the data - libcurl will not copy */
339 //curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
340
341 list = curl_slist_append(list, "Content-Type: application/json");
342
343 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
344
345 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&error);
346
347 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
348
349 /* now specify which file to upload */
350 curl_easy_setopt(curl, CURLOPT_READDATA, &file);
351
352 /* we want to use our own read function */
353 curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_data);
354
355 syslog(LOG_NOTICE, "cURL perform the request");
356 tslp_tsk(100);
357
358 /* Perform the request, res will get the return code */
359 res = curl_easy_perform(curl);
360 /* Check for errors */
361 if (res != CURLE_OK) {
362 syslog(LOG_ERROR, "curl_easy_perform() failed: %s\n",
363 curl_easy_strerror(res));
364 syslog(LOG_ERROR, errbuf);
365 }
366
367 /* always cleanup */
368 curl_easy_cleanup(curl);
369
370 syslog(LOG_NOTICE, "cURL end");
371
372file_close:
373 f_close(&file);
374}
375
376void client_fin(void)
377{
378 curl_global_cleanup();
379}
Note: See TracBrowser for help on using the repository browser.