source: uKadecot/trunk/kadecot/wamp_broker.c@ 152

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

・デジタルPinとアナログPinのWAMPトピックを追加し、PubSubできるように機能追加。

デジタルPINのトピックは、

「com.sonycsl.kadecot.arduino.topic.pinXX」(XXは0から13)

アナログPINのトピックは、

「com.sonycsl.kadecot.arduino.topic.pinXX.thrYYY」(XXは14から19、YYYは閾値十進)

・デバッグ用の使用していない文字列が、ROM領域に残ってしまうのを修正
・WebSocket接続時のHTTPヘッダーを1行ずつNAK応答を待って送信しているのを、一括で送るよう変更

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr; charset=SHIFT_JIS
File size: 15.9 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2015 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: wamp_broker.c 152 2016-01-14 04:17:21Z coas-nagasima $
36 */
37
38#include <string.h>
39#include <stdlib.h>
40#include "wamp.h"
41#include "wamp_broker.h"
42#include "main.h"
43#include "fbs_string.h"
44#include "kadecot_names.h"
45#include "kernel_cfg.h"
46
47#ifndef _MSC_VER
48#ifndef strncpy_s
49#define strncpy_s(dst, dsz, src, sz) strncpy(dst, src, sz)
50#endif
51
52#ifndef strcpy_s
53#define strcpy_s(s1, s1m, s2) strcpy(s1, s2)
54#endif
55#endif
56
57static wamp_subscription_t *wamp_broker_new_subscription(wamp_broker_t *broker);
58static void wamp_broker_delete_subscription(wamp_broker_t *broker,
59 wamp_subscription_t *subscription);
60
61void wamp_broker_subscribe(wamp_broker_t *broker)
62{
63 broker->current_subscription = NULL;
64}
65
66void wamp_broker_subscribe_request_id(wamp_broker_t *broker, const char *value)
67{
68 broker->requestId = atoi(value);
69}
70
71void wamp_broker_subscribe_options_param(wamp_broker_t *broker, jsonsl_action_t action,
72 struct jsonsl_state_st *state, const char *buf)
73{
74}
75
76void wamp_broker_subscribe_options(wamp_broker_t *broker)
77{
78}
79
80void wamp_broker_subscribe_topic(wamp_broker_t *broker, const char *value)
81{
82 static const char echonetlite_topic[] = "com.sonycsl.kadecot.echonetlite.topic.";
83 static const char arduino_topic[] = "com.sonycsl.kadecot.arduino.topic.";
84
85 if (strncmp(echonetlite_topic, value, sizeof(echonetlite_topic) - 1) == 0)
86 wamp_broker_subscribe_echonetlite_topic(broker, value, sizeof(echonetlite_topic) - 1);
87 else if (strncmp(arduino_topic, value, sizeof(arduino_topic) - 1) == 0)
88 wamp_broker_subscribe_arduino_topic(broker, value, sizeof(arduino_topic) - 1);
89}
90
91void wamp_broker_subscribe_echonetlite_topic(wamp_broker_t *broker, const char *value, int val_pos)
92{
93 char *pos, *end;
94 wamp_subscription_t *subscription;
95 wamp_echonetlite_subscription_t *echonetlite;
96 uint16_t devType;
97 uint8_t epc;
98
99 subscription = wamp_broker_new_subscription(broker);
100 if(subscription == NULL)
101 return;
102 subscription->kind = WAMP_SUBSCRIPTION_KIND_ECHONETLITE;
103 echonetlite = &subscription->echonetlite;
104
105 echonetlite->deviceName[0] = '\0';
106 strcpy_s(echonetlite->deviceName, sizeof(echonetlite->deviceName), &value[val_pos]);
107 echonetlite->deviceName[sizeof(echonetlite->deviceName) - 1] = '\0';
108
109 end = &echonetlite->deviceName[sizeof(echonetlite->deviceName)];
110 for(pos = echonetlite->deviceName; pos < end; pos++){
111 if(*pos != '.')
112 continue;
113
114 *pos = '\0';
115 echonetlite->proprtyName = pos + 1;
116 break;
117 }
118
119 devType = kadecot_names_get_device_type(echonetlite->deviceName,
120 strnlen(echonetlite->deviceName, sizeof(echonetlite->deviceName)));
121 if(devType == 0){
122 wamp_broker_delete_subscription(broker, subscription);
123 return;
124 }
125
126 epc = kadecot_names_get_property_code(echonetlite->proprtyName,
127 strnlen(echonetlite->proprtyName, echonetlite->proprtyName - echonetlite->deviceName), devType);
128 if(epc == 0){
129 wamp_broker_delete_subscription(broker, subscription);
130 return;
131 }
132
133 echonetlite->devType = devType;
134 echonetlite->epc = epc;
135
136 wamp_subscription_t *spos, *send = &broker->subscriptions[sizeof(broker->subscriptions) / sizeof(broker->subscriptions[0])];
137
138 for (spos = broker->subscriptions; spos < send; spos++) {
139 if ((spos == subscription) || (spos->subscriptionId == 0) || (spos->kind != WAMP_SUBSCRIPTION_KIND_ECHONETLITE))
140 continue;
141
142 if ((spos->echonetlite.devType != devType) || (spos->echonetlite.epc != epc))
143 continue;
144
145 wamp_broker_delete_subscription(broker, subscription);
146 subscription = spos;
147 break;
148 }
149
150 broker->current_subscription = subscription;
151}
152
153void wamp_broker_subscribe_arduino_topic(wamp_broker_t *broker, const char *value, int val_pos)
154{
155 char *pos, *end;
156 wamp_subscription_t *subscription;
157 wamp_arduino_subscription_t *arduino;
158 char pinno[40], *threshold = NULL;
159
160 subscription = wamp_broker_new_subscription(broker);
161 if (subscription == NULL)
162 return;
163 subscription->kind = WAMP_SUBSCRIPTION_KIND_ARDUINO;
164 arduino = &subscription->arduino;
165
166 pinno[0] = '\0';
167 strcpy_s(pinno, sizeof(pinno), &value[val_pos]);
168 pinno[sizeof(pinno) - 1] = '\0';
169
170 if (pinno[0] != 'p' || pinno[1] != 'i' || pinno[2] != 'n') {
171 wamp_broker_delete_subscription(broker, subscription);
172 return;
173 }
174
175 end = &pinno[sizeof(pinno)];
176 for (pos = pinno; pos < end; pos++) {
177 if (*pos != '.')
178 continue;
179
180 *pos = '\0';
181 threshold = pos + 1;
182 if (threshold[0] != 't' || threshold[1] != 'h' || threshold[2] != 'r') {
183 threshold = NULL;
184 }
185 break;
186 }
187
188 arduino->pinno = atoi(&pinno[3]);
189 if (threshold != NULL) {
190 arduino->threshold = atoi(&threshold[3]);
191 }
192 else {
193 arduino->threshold = 0;
194 }
195
196 wamp_subscription_t *spos, *send = &broker->subscriptions[sizeof(broker->subscriptions) / sizeof(broker->subscriptions[0])];
197
198 for (spos = broker->subscriptions; spos < send; spos++) {
199 if ((spos == subscription) || (spos->subscriptionId == 0) || (spos->kind != WAMP_SUBSCRIPTION_KIND_ARDUINO))
200 continue;
201
202 if ((spos->arduino.pinno != arduino->pinno) || (spos->arduino.threshold != arduino->threshold))
203 continue;
204
205 wamp_broker_delete_subscription(broker, subscription);
206 subscription = spos;
207 break;
208 }
209
210 broker->current_subscription = subscription;
211}
212
213static void wamp_broker_subscribe_echonetlite_res(wamp_broker_t *broker);
214static void wamp_broker_subscribe_arduino_res(wamp_broker_t *broker);
215
216void wamp_broker_subscribe_close(struct wamp_state *s)
217{
218 wamp_broker_t *broker = &s->broker;
219 ER ret;
220
221 broker->error = internal_error;
222
223 // send RESULT
224 if (broker->current_subscription != NULL) {
225 switch (broker->current_subscription->kind) {
226 case WAMP_SUBSCRIPTION_KIND_ECHONETLITE:
227 wamp_broker_subscribe_echonetlite_res(broker);
228 break;
229 case WAMP_SUBSCRIPTION_KIND_ARDUINO:
230 wamp_broker_subscribe_arduino_res(broker);
231 break;
232 default:
233 break;
234 }
235 }
236
237 if (broker->error != NULL){
238 ret = wamp_send_error_res(s, WAMP_CODE_SUBSCRIBE, broker->requestId, broker->error);
239 if (ret != E_OK) {
240 syslog(LOG_WARNING, "wamp_broker_subscribe_close() : wamp_send_error_res() result = %d", ret);
241 }
242 broker->error = NULL;
243 }
244}
245
246static void wamp_broker_subscribe_echonetlite_res(wamp_broker_t *broker)
247{
248 struct wamp_state *s = broker->s;
249 wamp_subscription_t *subscription = broker->current_subscription;
250 // send SUBSCRIBED or ERROR
251 ECN_FBS_ID buf;
252 ECN_FBS_SSIZE_T pos = 0;
253 ER ret;
254
255 if ((subscription == NULL) || (subscription->echonetlite.devType == 0) || (subscription->echonetlite.epc == 0))
256 return;
257
258 ret = _ecn_fbs_cre(1, &buf);
259 if (ret != E_OK) {
260 syslog(LOG_WARNING, "_ecn_fbs_cre() result = %d", ret);
261 return;
262 }
263
264 ret = fbs_printf(buf, &pos, "[33,%d,%d]", broker->requestId, subscription->subscriptionId);
265 if (ret != E_OK) {
266 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
267 _ecn_fbs_del(buf);
268 return;
269 }
270
271 ret = main_send_message(buf, s->wbsid);
272 if (ret != E_OK) {
273 syslog(LOG_WARNING, "wamp_broker_subscribe_echonetlite_res() : main_send_message() result = %d", ret);
274 return;
275 }
276
277 broker->error = NULL;
278}
279
280static void wamp_broker_subscribe_arduino_res(wamp_broker_t *broker)
281{
282 struct wamp_state *s = broker->s;
283 wamp_subscription_t *subscription = broker->current_subscription;
284 // send SUBSCRIBED or ERROR
285 ECN_FBS_ID buf;
286 ECN_FBS_SSIZE_T pos = 0;
287 ER ret;
288
289 if ((subscription == NULL)
290 || ((subscription->arduino.pinno < 0) || (subscription->arduino.pinno > 19)))
291 return;
292
293 if (subscription->arduino.pinno >= 14)
294 main_add_threshold(subscription->subscriptionId, subscription->arduino.pinno, subscription->arduino.threshold);
295
296 ret = _ecn_fbs_cre(1, &buf);
297 if (ret != E_OK) {
298 syslog(LOG_WARNING, "_ecn_fbs_cre() result = %d", ret);
299 return;
300 }
301
302 ret = fbs_printf(buf, &pos, "[33,%d,%d]", broker->requestId, subscription->subscriptionId);
303 if (ret != E_OK) {
304 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
305 _ecn_fbs_del(buf);
306 return;
307 }
308
309 ret = main_send_message(buf, s->wbsid);
310 if (ret != E_OK) {
311 syslog(LOG_WARNING, "wamp_broker_subscribe_arduino_res() : main_send_message() result = %d", ret);
312 return;
313 }
314
315 broker->error = NULL;
316}
317
318void wamp_broker_unsubscribe(wamp_broker_t *broker)
319{
320 broker->current_subscription = NULL;
321}
322
323void wamp_broker_unsubscribe_request_id(wamp_broker_t *broker, const char *value)
324{
325 broker->requestId = atoi(value);
326}
327
328void wamp_broker_unsubscribe_subscription_id(wamp_broker_t *broker, const char *value)
329{
330 int subscriptionId = atoi(value);
331 wamp_subscription_t *pos, *end = &broker->subscriptions[sizeof(broker->subscriptions) / sizeof(broker->subscriptions[0])];
332
333 for(pos = broker->subscriptions; pos < end; pos++){
334 if(pos->subscriptionId != subscriptionId)
335 continue;
336
337 broker->current_subscription = pos;
338 break;
339 }
340}
341
342void wamp_broker_unsubscribe_close(struct wamp_state *s)
343{
344 wamp_broker_t *broker = &s->broker;
345 wamp_subscription_t *subscription = broker->current_subscription;
346 // send UNSUBSCRIBED or ERROR
347 ECN_FBS_ID buf;
348 ECN_FBS_SSIZE_T pos = 0;
349 ER ret;
350
351 if(subscription == NULL)
352 return;
353
354 if (subscription->kind == WAMP_SUBSCRIPTION_KIND_ARDUINO)
355 main_del_threshold(subscription->subscriptionId);
356
357 wamp_broker_delete_subscription(broker, subscription);
358
359 ret = _ecn_fbs_cre(1, &buf);
360 if (ret != E_OK) {
361 syslog(LOG_WARNING, "_ecn_fbs_cre() result = %d", ret);
362 return;
363 }
364
365 ret = fbs_printf(buf, &pos, "[35,%d,%d]", broker->requestId, subscription->subscriptionId);
366 if (ret != E_OK) {
367 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
368 _ecn_fbs_del(buf);
369 return;
370 }
371
372 ret = main_send_message(buf, s->wbsid);
373 if (ret != E_OK) {
374 syslog(LOG_WARNING, "wamp_broker_unsubscribe_close() : main_send_message() result = %d", ret);
375 }
376}
377
378void wamp_broker_publish(wamp_broker_t *broker)
379{
380}
381
382void wamp_broker_publish_request_id(wamp_broker_t *s, const char *value)
383{
384}
385
386void wamp_broker_publish_options(wamp_broker_t *s, const char *value)
387{
388}
389
390void wamp_broker_publish_options_param(wamp_broker_t *s, jsonsl_action_t action,
391 struct jsonsl_state_st *state, const char *buf)
392{
393}
394
395void wamp_broker_publish_topic(wamp_broker_t *s, const char *value)
396{
397}
398
399void wamp_broker_publish_arguments(wamp_broker_t *s, const char *value)
400{
401}
402
403void wamp_broker_publish_arguments_param(wamp_broker_t *s, jsonsl_action_t action,
404 struct jsonsl_state_st *state, const char *buf)
405{
406}
407
408void wamp_broker_publish_argumentskw(wamp_broker_t *s, const char *value)
409{
410}
411
412void wamp_broker_publish_argumentskw_param(wamp_broker_t *s, jsonsl_action_t action,
413 struct jsonsl_state_st *state, const char *buf)
414{
415}
416
417void wamp_broker_publish_close(struct wamp_state *s)
418{
419}
420
421static wamp_subscription_t *wamp_broker_new_subscription(wamp_broker_t *broker)
422{
423 wamp_subscription_t *pos, *end = &broker->subscriptions[sizeof(broker->subscriptions) / sizeof(broker->subscriptions[0])];
424
425 for(pos = broker->subscriptions; pos < end; pos++){
426 if(pos->subscriptionId != 0)
427 continue;
428
429 broker->subscriptionId++;
430 if(broker->subscriptionId == 0)
431 broker->subscriptionId++;
432
433 pos->subscriptionId = broker->subscriptionId;
434 return pos;
435 }
436
437 return NULL;
438}
439
440static void wamp_broker_delete_subscription(wamp_broker_t *broker,
441 wamp_subscription_t *subscription)
442{
443 memset(subscription, 0, sizeof(*subscription));
444}
445
446void wamp_broker_publish_inf(wamp_broker_t *broker, uint16_t pubId, int deviceId,
447 uint16_t devType, uint8_t epc, uint8_t pdc, uint8_t *p_edt)
448{
449 struct wamp_state *s = broker->s;
450 wamp_subscription_t *subscription, *end = &broker->subscriptions[sizeof(broker->subscriptions) / sizeof(broker->subscriptions[0])];
451 ECN_FBS_ID buf;
452 ECN_FBS_SSIZE_T pos = 0, start;
453 ER ret;
454 int i;
455
456 for(subscription = broker->subscriptions; subscription < end; subscription++){
457 if ((subscription->subscriptionId == 0) || (subscription->kind != WAMP_SUBSCRIPTION_KIND_ECHONETLITE))
458 continue;
459
460 if ((subscription->echonetlite.devType != devType) || (subscription->echonetlite.epc != epc))
461 continue;
462
463 ret = _ecn_fbs_cre(1, &buf);
464 if (ret != E_OK) {
465 syslog(LOG_WARNING, "_ecn_fbs_cre() result = %d", ret);
466 break;
467 }
468
469 ret = fbs_printf(buf, &pos, "[36,%d,%d,{\"deviceId\":%d},[],",
470 subscription->subscriptionId, pubId, deviceId);
471 if (ret != E_OK) {
472 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
473 _ecn_fbs_del(buf);
474 break;
475 }
476
477 ret = fbs_printf(buf, &pos, "{\"propertyName\":\"%s\",\"propertyValue\":[",
478 subscription->echonetlite.proprtyName);
479 if (ret != E_OK) {
480 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
481 _ecn_fbs_del(buf);
482 break;
483 }
484
485 start = pos;
486 for(i = 0; i < pdc; i++){
487 ret = fbs_printf(buf, &pos, "%d,", p_edt[i]);
488 if (ret != E_OK) {
489 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
490 _ecn_fbs_del(buf);
491 break;
492 }
493 }
494
495 /* 最後の","を消す */
496 if(start != pos)
497 pos--;
498
499 ret = fbs_printf(buf, &pos, "]}]");
500 if (ret != E_OK) {
501 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
502 _ecn_fbs_del(buf);
503 break;
504 }
505
506 ret = main_send_message(buf, s->wbsid);
507 if (ret != E_OK) {
508 syslog(LOG_WARNING, "wamp_broker_publish_inf() : main_send_message() result = %d", ret);
509 }
510 break;
511 }
512}
513
514void wamp_broker_publish_pin(wamp_broker_t *broker, uint16_t pubId, int deviceId, int pinno, uint16_t value)
515{
516 struct wamp_state *s = broker->s;
517 wamp_subscription_t *subscription, *end = &broker->subscriptions[sizeof(broker->subscriptions) / sizeof(broker->subscriptions[0])];
518 ECN_FBS_ID buf;
519 ECN_FBS_SSIZE_T pos = 0;
520 ER ret;
521
522 for (subscription = broker->subscriptions; subscription < end; subscription++) {
523 if ((subscription->subscriptionId == 0) || (subscription->kind != WAMP_SUBSCRIPTION_KIND_ARDUINO))
524 continue;
525
526 if (subscription->arduino.pinno != pinno)
527 continue;
528
529 ret = _ecn_fbs_cre(1, &buf);
530 if (ret != E_OK) {
531 syslog(LOG_WARNING, "_ecn_fbs_cre() result = %d", ret);
532 break;
533 }
534
535 ret = fbs_printf(buf, &pos, "[36,%d,%d,{\"deviceId\":%d},[],",
536 subscription->subscriptionId, pubId, deviceId);
537 if (ret != E_OK) {
538 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
539 _ecn_fbs_del(buf);
540 break;
541 }
542
543 if ((pinno >= 0) && (pinno <= 13)) {
544 ret = fbs_printf(buf, &pos, "{\"pin\":%d,\"value\":\"%s\"}]",
545 subscription->arduino.pinno, (value == 0) ? "LOW" : "HIGH");
546 if (ret != E_OK) {
547 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
548 _ecn_fbs_del(buf);
549 break;
550 }
551 }
552 else {
553 ret = fbs_printf(buf, &pos, "{\"pin\":%d,\"value\":%d}]",
554 subscription->arduino.pinno, value);
555 if (ret != E_OK) {
556 syslog(LOG_WARNING, "fbs_printf() result = %d", ret);
557 _ecn_fbs_del(buf);
558 break;
559 }
560 }
561
562 ret = main_send_message(buf, s->wbsid);
563 if (ret != E_OK) {
564 syslog(LOG_WARNING, "wamp_broker_publish_inf() : main_send_message() result = %d", ret);
565 }
566 break;
567 }
568}
Note: See TracBrowser for help on using the repository browser.