00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00137 #include <avr/io.h>
00138 #include <avr/pgmspace.h>
00139 #include <avr/eeprom.h>
00140 #include <inttypes.h>
00141 #include <stddef.h>
00142 #include "net/application.h"
00143 #include "net/network.h"
00144 #include "net/link.h"
00145 #include "net/buffers.h"
00146 #include "net.h"
00147 #include "utils.h"
00148
00149
00155 typedef struct {
00156 net_addr_t addr;
00157 enum tsp_service_e service;
00158 uint8_t assoc;
00159 } event_desc_t;
00160
00164 typedef struct {
00165 uint8_t id;
00166 uint8_t obj;
00167 uint8_t method;
00168 } assoc_t;
00169
00173 typedef struct {
00174 uint8_t obj;
00175 uint8_t event;
00176 } event_t;
00177
00178
00179 static void __sys_obj_method(void *self, uint8_t property, uint8_t *buf, uint8_t *result, uint8_t repeated);
00180 static param_desc_t __sys_obj_prop[];
00181
00182 #ifdef APP_STATIC
00183 #define READ_WORD(x) pgm_read_word(&(x))
00184
00185
00186 static struct AppObject PROGMEM __sys_obj = {__sys_obj_prop, NULL, __sys_obj_method};
00187
00188
00189 #define OBJECT(x, y) extern struct AppObject PROGMEM x;
00190 APP_OBJECTS
00191 #undef OBJECT
00192
00193
00194 #define OBJECT(x, y) event_desc_t x##_ev[y] EEPROM;
00195 APP_OBJECTS
00196 #undef OBJECT
00197
00198
00199 #define OBJECT(x, y) ,&x
00200 static const struct AppObject * PROGMEM app_object_table[] = {&__sys_obj APP_OBJECTS};
00201 #undef OBJECT
00202
00203
00204 #define OBJECT(x, y) ,x##_ev
00205 static event_desc_t * PROGMEM events_table[] = {NULL APP_OBJECTS};
00206 #undef OBJECT
00207 #else
00208 #define READ_WORD(x) (x)
00209 extern char __eeprom_end;
00210
00211
00212 static struct AppObject __sys_obj = {__sys_obj_prop, NULL, __sys_obj_method};
00213
00214
00215 static struct AppObject * app_object_table[16];
00216 static event_desc_t *events_table[16];
00217
00218 static uint8_t next_obj = 1;
00219 void *next_eeprom_addr = &__eeprom_end;
00220 #endif
00221
00222
00223 assoc_t ee_assoc[APP_MAX_ASSOC] EEPROM;
00224
00225
00226 static net_buf_t buffer_info;
00227 static struct main_buf_t {
00228 uint8_t header[13];
00229 uint8_t data[APP_BUFFER_SIZE];
00230 } buffer;
00231 static uint8_t lock;
00232
00233
00234 static event_t event_buffer[APP_MAX_EVENTS];
00235 static uint8_t event_rd, event_wr;
00236 static net_addr_t dest;
00237
00238
00239
00240
00241
00242 #define SYS_ADDR_LOGIC_SET 0
00243 #define SYS_ADDR_LOGIC_GET 1
00244 #define SYS_ADDR_GROUP_SET 2
00245 #define SYS_ADDR_GROUP_GET 3
00246 #define SYS_SIZE_SEGMENT_SET 4
00247 #define SYS_SIZE_SEGMENT_GET 5
00248 #define SYS_SIZE_GROUP_SET 6
00249 #define SYS_SIZE_GROUP_GET 7
00250 #define SYS_ASSOC_SET 8
00251 #define SYS_ASSOC_GET 9
00252 #define SYS_GET_ERROR_STATS 10
00253
00254 static param_desc_t __sys_obj_prop[] = {{2,0}, {0,2}, {3,0}, {1,2}, {1,0},
00255 {0,1}, {2,0}, {1,1}, {4,0}, {1,3}, {0,8}};
00256
00257 static void __sys_obj_method(void *self, uint8_t method, uint8_t *buf, uint8_t *result, uint8_t repeated)
00258 {
00259 switch (method) {
00260 case SYS_ADDR_LOGIC_SET:
00261 net_set_logic_addr(*((uint16_t*)buf));
00262 break;
00263 case SYS_ADDR_LOGIC_GET:
00264 *(uint16_t*)result = net_get_logic_addr();
00265 break;
00266 case SYS_ADDR_GROUP_SET:
00267 net_set_group_addr(buf[0], *((uint16_t*)(buf+1)));
00268 break;
00269 case SYS_ADDR_GROUP_GET:
00270 *((uint16_t*)result) = net_get_group_addr(buf[0]);
00271 break;
00272 case SYS_SIZE_SEGMENT_SET:
00273 tsp_set_segment_size(buf[0]);
00274 break;
00275 case SYS_SIZE_SEGMENT_GET:
00276 *result = tsp_get_segment_size();
00277 break;
00278 case SYS_SIZE_GROUP_SET:
00279 tsp_set_group_size(buf[0], buf[1]);
00280 break;
00281 case SYS_SIZE_GROUP_GET:
00282 *result = tsp_get_group_size(buf[0]);
00283 break;
00284 case SYS_ASSOC_SET:
00285 eeprom_write_byte(&ee_assoc[buf[0]].obj, buf[1]);
00286 eeprom_write_byte(&ee_assoc[buf[0]].method, buf[2]);
00287
00288 break;
00289 case SYS_ASSOC_GET:
00290 result[0] = eeprom_read_byte(&ee_assoc[buf[0]].obj);
00291 result[1] = eeprom_read_byte(&ee_assoc[buf[0]].method);
00292
00293 break;
00294 case SYS_GET_ERROR_STATS:
00295 lnk_get_error_stats((struct lnk_err_t *)result);
00296 break;
00297 }
00298 }
00299
00309 static void call_method(uint8_t obj, uint8_t method, uint8_t *buf, uint8_t len, uint8_t session)
00310 {
00311 struct AppObject *app;
00312 appObjCallback_t *obj_method;
00313 param_desc_t *params;
00314 event_desc_t *event;
00315
00316
00317 if ((method&0x80) != 0) {
00318 event = (event_desc_t*)READ_WORD(events_table[obj]);
00319
00320 if ((session != 2) && (len == sizeof(event_desc_t))) {
00321 eeprom_write_block(&event[method&0x7f], buf, sizeof(event_desc_t));
00322 }
00323
00324 if (session) {
00325 lock = 1;
00326 buf_init(buffer_info, &buffer.data, sizeof(event_desc_t));
00327 eeprom_read_block(&buffer.data, &event[method&0x7f], sizeof(event_desc_t));
00328 }
00329 } else {
00330 app = (struct AppObject*)READ_WORD(app_object_table[obj]);
00331 params = (param_desc_t*)READ_WORD(app->method_sizes);
00332 if (len != PRG_RDB(¶ms[method].in)) return;
00333
00334 obj_method = (appObjCallback_t*)READ_WORD(app->Callback);
00335 if (session) {
00336 lock = 1;
00337 buf_init(buffer_info, &buffer.data, PRG_RDB(¶ms[method].out));
00338 obj_method(app, method, buf, buffer.data, session==2);
00339 } else {
00340 obj_method(app, method, buf, NULL, 0);
00341 }
00342 }
00343 }
00344
00345
00346
00347
00348
00359 net_buf_t *tsp_ind(uint8_t *buf, uint8_t len, uint8_t session)
00360 {
00361 uint8_t obj, method, cnt, id;
00362
00363
00364 if ((session) && (lock != 0)) return NULL;
00365
00366
00367 if (buf[0] < 32) {
00368
00369 obj = buf[0];
00370 method = buf[1];
00371 call_method(obj, method, buf+2, len-2, session);
00372 } else {
00373
00374 len--;
00375 cnt = 0;
00376 do {
00377 id = eeprom_read_byte(&ee_assoc[cnt].id);
00378 if (id == buf[0]) {
00379 obj = eeprom_read_byte(&ee_assoc[cnt].obj);
00380 method = eeprom_read_byte(&ee_assoc[cnt].method);
00381 call_method(obj, method, buf+1, len, session);
00382 }
00383 cnt++;
00384 } while ((cnt < APP_MAX_ASSOC) && (id <= buf[0]));
00385 }
00386
00387 return &buffer_info;
00388 }
00389
00396 void tsp_con(uint8_t *buf, uint8_t len)
00397 {
00398 uint8_t obj, event;
00399 struct AppObject *app;
00400 appObjCallback_t *obj_method;
00401
00402
00403 obj = event_buffer[event_rd].obj;
00404 event = event_buffer[event_rd].event;
00405
00406
00407 app = (struct AppObject*)READ_WORD(app_object_table[obj]);
00408 obj_method = (appObjCallback_t*)READ_WORD(app->Callback);
00409 obj_method(app, event|0x80, buf, NULL, 0);
00410 }
00411
00417 void tsp_con_fin(uint8_t status)
00418 {
00419 lock = 0;
00420 }
00421
00422
00423
00424
00425
00431 void app_init(void)
00432 {
00433 #ifndef APP_STATIC
00434 app_object_table[0] = &__sys_obj;
00435 #endif
00436 }
00437
00446 void app_process(void)
00447 {
00448 struct AppObject *app;
00449 appObjCallback_t *obj_method;
00450 param_desc_t *params;
00451 event_desc_t *ed;
00452 uint8_t len, obj, event;
00453 enum tsp_service_e service;
00454
00455
00456 if (!tsp_clear_to_send() || (lock != 0)) return;
00457
00458
00459 if (event_rd != event_wr) {
00460
00461 obj = event_buffer[(event_rd+1)&(APP_MAX_EVENTS-1)].obj;
00462 event = event_buffer[(event_rd+1)&(APP_MAX_EVENTS-1)].event;
00463
00464
00465 app = (struct AppObject*)READ_WORD(app_object_table[obj]);
00466 params = (param_desc_t*)READ_WORD(app->event_sizes);
00467 len = PRG_RDB(¶ms[event].out);
00468 buf_init(buffer_info, &buffer.data, len);
00469
00470
00471 obj_method = (appObjCallback_t*)READ_WORD(app->Callback);
00472 obj_method(app, event|0x80, NULL, buffer.data, 0);
00473
00474
00475 ed = (event_desc_t*)READ_WORD(events_table[obj]);
00476 eeprom_read_block(&dest, &ed[event].addr, sizeof(net_addr_t));
00477 service = (enum tsp_service_e)eeprom_read_byte(&ed[event].service);
00478 buf_prep_char(&buffer_info, eeprom_read_byte(&ed[event].assoc));
00479
00480
00481 switch (tsp_requ(&buffer_info, &dest, service)) {
00482 case 1:
00483 lock = 1;
00484 case -1:
00485 event_rd = (event_rd+1)&(APP_MAX_EVENTS-1);
00486 default:
00487 break;
00488 }
00489 }
00490 }
00491
00500 void app_trigger_event(uint8_t obj, uint8_t event)
00501 {
00502 event_wr = (event_wr+1)&(APP_MAX_EVENTS-1);
00503 event_buffer[event_wr].obj = obj;
00504 event_buffer[event_wr].event = event;
00505 }
00506
00507 #ifndef APP_STATIC
00508
00519 uint8_t app_register_obj(struct AppObject *obj, uint8_t events)
00520 {
00521 app_object_table[next_obj] = obj;
00522 events_table[next_obj] = next_eeprom_addr;
00523 (uint8_t*)next_eeprom_addr += events*sizeof(event_desc_t);
00524 return next_obj++;
00525 }
00526
00527 #endif