00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00036 #include <avr/eeprom.h>
00037 #include <avr/pgmspace.h>
00038 #include <inttypes.h>
00039 #include "net/link.h"
00040 #include "net/network.h"
00041 #include "net.h"
00042 #include "utils.h"
00043
00044
00045 static net_ind_t ind;
00046
00047
00048 uint16_t ee_addr_logic __attribute__(( section(".eeprom") ));
00049 uint16_t ee_addr_group[8] __attribute__(( section(".eeprom") ));
00050
00051
00052 static prog_uchar dest_length_table[] = {2,1,4,0};
00053 static prog_uchar src_length_table[] = {2,2,4,0};
00054
00055
00056 #define DAF_MASK 0x03
00057 #define SAF_MASK 0x0c
00058 #define PDU_MASK 0x30
00059
00060
00061 extern void net_ind(uint8_t *buf, uint8_t len, const net_ind_t *ind);
00062 extern void net_con(void);
00063
00064
00065
00066
00067
00086 uint8_t lnk_ind(uint8_t *buf, uint8_t len)
00087 {
00088 uint8_t i, src_offset, src_len, result;
00089
00090
00091 result = 0;
00092 switch (buf[0] & DAF_MASK) {
00093 case NAF_LOGIC:
00094 if (*(uint16_t*)(buf+1) == eeprom_read_word(&ee_addr_logic)) {
00095 ind.rat = AT_LOGIC;
00096 result = 1;
00097 goto addr_match;
00098 }
00099 break;
00100 case NAF_GROUP:
00101 for (i=0;i<8;i++)
00102 if (buf[1] == eeprom_read_byte(&ee_addr_group[i])) {
00103 ind.rat = AT_GROUP0+i;
00104 goto addr_match;
00105 }
00106 break;
00107 case NAF_PHYSIC:
00108 if (*(uint32_t*)(buf+1) == NET_PHYSICAL_ADDR) {
00109 result = 1;
00110 ind.rat = AT_PHYSIC;
00111 goto addr_match;
00112 }
00113 break;
00114 case NAF_BROADCAST:
00115 ind.rat = AT_PHYSIC;
00116 goto addr_match;
00117 default:
00118 break;
00119 }
00120 return 0;
00121
00122 addr_match:
00123 ind.pdu = (buf[0]>>4) & 0x03;
00124 ind.src.format = (buf[0] & SAF_MASK) >> 2;
00125 src_len = __LPM(&src_length_table[ind.src.format]);
00126 src_offset = __LPM(&dest_length_table[buf[0] & DAF_MASK])+1;
00127 buf += src_offset;
00128 for (i=0;i<src_len;i++) ind.src.addr[i] = *buf++;
00129 len -= src_len+src_offset;
00130 net_ind(buf, len, &ind);
00131 return result;
00132 }
00133
00139 void lnk_con(void)
00140 {
00141 net_con();
00142 }
00143
00144
00145
00146
00147
00162 uint8_t net_requ(net_buf_t *buf, const net_requ_t *requ)
00163 {
00164 uint8_t hdr, i;
00165
00166
00167 if (!lnk_clear_to_send()) return 0;
00168
00169
00170 hdr = (requ->pdu << 4) | requ->dest.format;
00171
00172
00173 if (requ->src == AT_LOGIC) {
00174 hdr |= NAF_LOGIC << 2;
00175 buf_prep_int(buf, eeprom_read_word(&ee_addr_logic));
00176 } else if (requ->src == AT_PHYSIC) {
00177 hdr |= NAF_PHYSIC << 2;
00178 buf_prep_long(buf, NET_PHYSICAL_ADDR);
00179 } else {
00180 hdr |= NAF_GROUP << 2;
00181 buf_prep_int(buf, eeprom_read_word(&ee_addr_group[requ->src-AT_GROUP0]));
00182 }
00183
00184
00185 i = __LPM(&dest_length_table[requ->dest.format]);
00186 while (i > 0) buf_prep_char(buf, requ->dest.addr[--i]);
00187
00188
00189 buf_prep_char(buf, hdr);
00190
00191
00192 if (lnk_ind(buf->data, buf->len)) {
00193 net_con();
00194 return 1;
00195 } else {
00196 return lnk_requ(buf, requ->backlog);
00197 }
00198 }
00199
00210 uint8_t net_compare_src_addr(const net_addr_t *addr1, const net_addr_t *addr2)
00211 {
00212 uint8_t i, len;
00213
00214 if (addr1->format != addr2->format) return 0;
00215 len = __LPM(&src_length_table[addr1->format]);
00216 for (i=0;i<len;i++) if (addr1->addr[i] != addr2->addr[i]) return 0;
00217 return 1;
00218 }
00219
00227 uint8_t net_get_local_member_id(uint8_t group)
00228 {
00229 return eeprom_read_byte(&ee_addr_group[group-AT_GROUP0]+1);
00230 }
00231
00238 uint8_t net_clear_to_send(void)
00239 {
00240 return lnk_clear_to_send();
00241 }
00242
00248 void net_set_logic_addr(uint16_t addr)
00249 {
00250 eeprom_write_word(&ee_addr_logic, addr);
00251 }
00252
00258 uint16_t net_get_logic_addr(void)
00259 {
00260 return eeprom_read_word(&ee_addr_logic);
00261 }
00262
00269 void net_set_group_addr(uint8_t group, uint16_t addr)
00270 {
00271 eeprom_write_word(&ee_addr_group[group], addr);
00272 }
00273
00280 uint16_t net_get_group_addr(uint8_t group)
00281 {
00282 return eeprom_read_word(&ee_addr_group[group]);
00283 }