update to contiki 3.0
This commit is contained in:
commit
500078ef9a
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -24,6 +24,7 @@
|
|||
*.c128
|
||||
*.c64
|
||||
*.cc2538dk
|
||||
*.remote
|
||||
*.srf06-cc26xx
|
||||
*.ev-aducrf101mkxz
|
||||
*.report
|
||||
|
@ -79,7 +80,7 @@ contiki-cc2530dk.lib
|
|||
*.S
|
||||
*.eth
|
||||
*.dsk
|
||||
*.2mg
|
||||
*.po
|
||||
*.atr
|
||||
*.d64
|
||||
*.d71
|
||||
|
|
7
.gitmodules
vendored
7
.gitmodules
vendored
|
@ -7,7 +7,10 @@
|
|||
[submodule "platform/osd-merkur/dev/LED_Strip_Suli"]
|
||||
path = platform/osd-merkur/dev/LED_Strip_Suli
|
||||
url = https://github.com/osdomotics/LED_Strip_Suli.git
|
||||
[submodule "cpu/cc26xx/lib/cc26xxware"]
|
||||
path = cpu/cc26xx/lib/cc26xxware
|
||||
[submodule "cpu/cc26xx-cc13xx/lib/cc26xxware"]
|
||||
path = cpu/cc26xx-cc13xx/lib/cc26xxware
|
||||
url = https://github.com/g-oikonomou/cc26xxware.git
|
||||
[submodule "cpu/cc26xx-cc13xx/lib/cc13xxware"]
|
||||
path = cpu/cc26xx-cc13xx/lib/cc13xxware
|
||||
url = https://github.com/g-oikonomou/cc13xxware.git
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ before_script:
|
|||
|
||||
## Install doxygen
|
||||
- if [ ${BUILD_CATEGORY:-0} = doxygen ] ; then
|
||||
sudo add-apt-repository ppa:libreoffice/libreoffice-4-3 -y && sudo apt-get -qq update &&
|
||||
sudo add-apt-repository ppa:libreoffice/libreoffice-4-4 -y && sudo apt-get -qq update &&
|
||||
sudo apt-get --no-install-suggests --no-install-recommends -qq install doxygen &&
|
||||
doxygen --version ;
|
||||
fi
|
||||
|
|
|
@ -136,7 +136,7 @@ Contiki maintainers to look at!
|
|||
All code contributions to Contiki are submitted as [Github pull
|
||||
requests](https://help.github.com/articles/using-pull-requests). Pull
|
||||
requests will be reviewed and accepted according to the guidelines
|
||||
found in the [[Pull Request Policy]]
|
||||
found in the next section.
|
||||
|
||||
The basic guidelines to to start a Pull-Request:
|
||||
* Create a new branch for your modifications. This branch should be based on the latest contiki master branch.
|
||||
|
@ -183,6 +183,21 @@ $ git push origin my_new_feature -f
|
|||
```
|
||||
* NOTE: To avoid all the pain of selectively picking commits, rebasing and force-pushing - begin your development with a branch OTHER THAN your master branch, and push changes to that branch after any local commits.
|
||||
|
||||
Pull Request Merging Policy
|
||||
---------------------------
|
||||
|
||||
Pull requests (PRs) are reviewed by the [merge team](https://github.com/orgs/contiki-os/people).
|
||||
Generally, PRs require two "+1" before they can be merged by someone on the merge team.
|
||||
The since Contiki 3.0, the merging policy is the following:
|
||||
* The PR receives **one "-1"** from a merge team member (along with specific feedback). The PR is closed. A "-1" must be accompanied with a clear explanation why the PR will not be considered for inclusion.
|
||||
* The PR receives **two "+1"** from merge team members. The PR is merged.
|
||||
* The PR was inactive for **two months**. A team member may either:
|
||||
* Comment "Is there any interest for this PR? Is there any work pending on it? If not I will close it in **one month**." Back to initial state in case of activity, close otherwise.
|
||||
* Comment "I approve this PR. If nobody disapproves within **one month**, I will merge it." Back to initial state in case of activity, merge otherwise.
|
||||
|
||||
There is an exception to the rule.
|
||||
Code that requires esoteric expertise such as some applications, platforms or tools can be merged after a single "+1" from its domain expert.
|
||||
|
||||
Travis / Regression testing
|
||||
---------------------------
|
||||
|
||||
|
|
|
@ -147,7 +147,6 @@ endif
|
|||
|
||||
ifdef MODULES
|
||||
UNIQUEMODULES = $(call uniq,$(MODULES))
|
||||
MODULESSUBST = ${subst /,-,$(UNIQUEMODULES)}
|
||||
MODULEDIRS = ${wildcard ${addprefix $(CONTIKI)/, $(UNIQUEMODULES)}}
|
||||
MODULES_SOURCES = ${foreach d, $(MODULEDIRS), ${subst ${d}/,,${wildcard $(d)/*.c}}}
|
||||
CONTIKI_SOURCEFILES += $(MODULES_SOURCES)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
The Contiki Operating System
|
||||
============================
|
||||
|
||||
[![Build Status](https://secure.travis-ci.org/contiki-os/contiki.png)](http://travis-ci.org/contiki-os/contiki)
|
||||
[![Build Status](https://travis-ci.org/contiki-os/contiki.svg?branch=master)](https://travis-ci.org/contiki-os/contiki/branches)
|
||||
|
||||
Contiki is an open source operating system that runs on tiny low-power
|
||||
microcontrollers and makes it possible to develop applications that
|
||||
|
|
|
@ -116,7 +116,6 @@ PROCESS_THREAD(dhcp_process, ev, data)
|
|||
ctk_window_open(&window);
|
||||
dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr));
|
||||
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
|
||||
|
@ -125,7 +124,7 @@ PROCESS_THREAD(dhcp_process, ev, data)
|
|||
dhcpc_request();
|
||||
set_statustext("Requesting...");
|
||||
}
|
||||
} else if(ev == tcpip_event) {
|
||||
} else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) {
|
||||
dhcpc_appcall(ev, data);
|
||||
} else if(ev == PROCESS_EVENT_EXIT ||
|
||||
ev == ctk_signal_window_close) {
|
||||
|
|
|
@ -104,7 +104,7 @@ coap_receive(void)
|
|||
coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport))) {
|
||||
uint32_t block_num = 0;
|
||||
uint16_t block_size = REST_MAX_CHUNK_SIZE;
|
||||
uint16_t block_size = COAP_MAX_BLOCK_SIZE;
|
||||
uint32_t block_offset = 0;
|
||||
int32_t new_offset = 0;
|
||||
|
||||
|
@ -125,8 +125,8 @@ coap_receive(void)
|
|||
if(coap_get_header_block2
|
||||
(message, &block_num, NULL, &block_size, &block_offset)) {
|
||||
PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n",
|
||||
block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset);
|
||||
block_size = MIN(block_size, REST_MAX_CHUNK_SIZE);
|
||||
block_num, block_size, COAP_MAX_BLOCK_SIZE, block_offset);
|
||||
block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
|
||||
new_offset = block_offset;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
PROCESS(shell_ls_process, "ls");
|
||||
SHELL_COMMAND(ls_command,
|
||||
"ls",
|
||||
"ls: list files",
|
||||
"ls <dirname>: list files",
|
||||
&shell_ls_process);
|
||||
PROCESS(shell_append_process, "append");
|
||||
SHELL_COMMAND(append_command,
|
||||
|
@ -82,7 +82,8 @@ PROCESS_THREAD(shell_ls_process, ev, data)
|
|||
char buf[32];
|
||||
PROCESS_BEGIN();
|
||||
|
||||
if(cfs_opendir(&dir, "/") != 0) {
|
||||
if(data != NULL) {
|
||||
if(cfs_opendir(&dir, data) != 0) {
|
||||
shell_output_str(&ls_command, "Cannot open directory", "");
|
||||
} else {
|
||||
totsize = 0;
|
||||
|
@ -96,6 +97,7 @@ PROCESS_THREAD(shell_ls_process, ev, data)
|
|||
sprintf(buf, "%lu", (unsigned long)totsize);
|
||||
shell_output_str(&ls_command, "Total size: ", buf);
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -62,6 +62,10 @@ static char telnetd_reject_text[] =
|
|||
"Too many connections, please try again later.";
|
||||
#endif
|
||||
|
||||
#ifndef TELNETD_CONF_MAX_IDLE_TIME
|
||||
#define TELNETD_CONF_MAX_IDLE_TIME (CLOCK_SECOND * 30)
|
||||
#endif
|
||||
|
||||
struct telnetd_state {
|
||||
char buf[TELNETD_CONF_LINELEN + 1];
|
||||
char bufptr;
|
||||
|
@ -74,7 +78,9 @@ struct telnetd_state {
|
|||
#define STATE_DO 4
|
||||
#define STATE_DONT 5
|
||||
#define STATE_CLOSE 6
|
||||
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||
struct timer silence_timer;
|
||||
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||
};
|
||||
static struct telnetd_state s;
|
||||
|
||||
|
@ -102,8 +108,6 @@ static struct telnetd_buf buf;
|
|||
|
||||
static uint8_t connected;
|
||||
|
||||
#define MAX_SILENCE_TIME (CLOCK_SECOND * 30)
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
buf_init(struct telnetd_buf *buf)
|
||||
|
@ -169,6 +173,8 @@ shell_prompt(char *str)
|
|||
void
|
||||
shell_default_output(const char *str1, int len1, const char *str2, int len2)
|
||||
{
|
||||
static const char crnl[2] = {ISO_cr, ISO_nl};
|
||||
|
||||
if(len1 > 0 && str1[len1 - 1] == '\n') {
|
||||
--len1;
|
||||
}
|
||||
|
@ -183,7 +189,7 @@ shell_default_output(const char *str1, int len1, const char *str2, int len2)
|
|||
#endif /* TELNETD_CONF_GUI */
|
||||
buf_append(&buf, str1, len1);
|
||||
buf_append(&buf, str2, len2);
|
||||
buf_append(&buf, "\r\n", 2);
|
||||
buf_append(&buf, crnl, sizeof(crnl));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -359,7 +365,9 @@ telnetd_appcall(void *ts)
|
|||
s.state = STATE_NORMAL;
|
||||
connected = 1;
|
||||
shell_start();
|
||||
timer_set(&s.silence_timer, MAX_SILENCE_TIME);
|
||||
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||
timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME);
|
||||
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||
ts = (char *)0;
|
||||
} else {
|
||||
uip_send(telnetd_reject_text, strlen(telnetd_reject_text));
|
||||
|
@ -381,11 +389,15 @@ telnetd_appcall(void *ts)
|
|||
connected = 0;
|
||||
}
|
||||
if(uip_acked()) {
|
||||
timer_set(&s.silence_timer, MAX_SILENCE_TIME);
|
||||
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||
timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME);
|
||||
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||
acked();
|
||||
}
|
||||
if(uip_newdata()) {
|
||||
timer_set(&s.silence_timer, MAX_SILENCE_TIME);
|
||||
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||
timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME);
|
||||
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||
newdata();
|
||||
}
|
||||
if(uip_rexmit() ||
|
||||
|
@ -394,16 +406,20 @@ telnetd_appcall(void *ts)
|
|||
uip_connected() ||
|
||||
uip_poll()) {
|
||||
senddata();
|
||||
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||
if(s.numsent > 0) {
|
||||
timer_set(&s.silence_timer, MAX_SILENCE_TIME);
|
||||
timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME);
|
||||
}
|
||||
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||
}
|
||||
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||
if(uip_poll()) {
|
||||
if(timer_expired(&s.silence_timer)) {
|
||||
uip_close();
|
||||
tcp_markconn(uip_conn, NULL);
|
||||
}
|
||||
}
|
||||
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -9,7 +9,6 @@ html_a "a\0"
|
|||
html_body "body\0"
|
||||
html_br "br\0"
|
||||
html_form "form\0"
|
||||
html_frame "frame\0"
|
||||
html_h1 "h1\0"
|
||||
html_h2 "h2\0"
|
||||
html_h3 "h3\0"
|
||||
|
|
|
@ -31,9 +31,6 @@ const char html_br[4] =
|
|||
const char html_form[6] =
|
||||
/* "form\0" */
|
||||
{0x66, 0x6f, 0x72, 0x6d, 00, };
|
||||
const char html_frame[7] =
|
||||
/* "frame\0" */
|
||||
{0x66, 0x72, 0x61, 0x6d, 0x65, 00, };
|
||||
const char html_h1[4] =
|
||||
/* "h1\0" */
|
||||
{0x68, 0x31, 00, };
|
||||
|
|
|
@ -9,7 +9,6 @@ extern const char html_a[3];
|
|||
extern const char html_body[6];
|
||||
extern const char html_br[4];
|
||||
extern const char html_form[6];
|
||||
extern const char html_frame[7];
|
||||
extern const char html_h1[4];
|
||||
extern const char html_h2[4];
|
||||
extern const char html_h3[4];
|
||||
|
|
|
@ -119,9 +119,6 @@ G * (<br>, <p>, <h>), the <li> tag (but does not even try to
|
|||
#define ISO_eq 0x3d
|
||||
#define ISO_gt 0x3e
|
||||
|
||||
#define ISO_rbrack 0x5b
|
||||
#define ISO_lbrack 0x5d
|
||||
|
||||
#define MINORSTATE_NONE 0
|
||||
#define MINORSTATE_TEXT 1 /* Parse normal text */
|
||||
#define MINORSTATE_EXTCHAR 2 /* Check for semi-colon */
|
||||
|
@ -140,7 +137,7 @@ G * (<br>, <p>, <h>), the <li> tag (but does not even try to
|
|||
#define MAJORSTATE_LINK 2
|
||||
#define MAJORSTATE_FORM 3
|
||||
#define MAJORSTATE_DISCARD 4
|
||||
|
||||
#define MAJORSTATE_SCRIPT 5
|
||||
|
||||
struct htmlparser_state {
|
||||
|
||||
|
@ -151,7 +148,7 @@ struct htmlparser_state {
|
|||
unsigned char tagattrptr;
|
||||
char tagattrparam[WWW_CONF_MAX_URLLEN + 1];
|
||||
unsigned char tagattrparamptr;
|
||||
unsigned char lastchar, quotechar;
|
||||
unsigned char quotechar;
|
||||
unsigned char majorstate, lastmajorstate;
|
||||
char linkurl[WWW_CONF_MAX_URLLEN + 1];
|
||||
|
||||
|
@ -196,33 +193,31 @@ static const char *tags[] = {
|
|||
html_br,
|
||||
#define TAG_FORM 10
|
||||
html_form,
|
||||
#define TAG_FRAME 11
|
||||
html_frame,
|
||||
#define TAG_H1 12
|
||||
#define TAG_H1 11
|
||||
html_h1,
|
||||
#define TAG_H2 13
|
||||
#define TAG_H2 12
|
||||
html_h2,
|
||||
#define TAG_H3 14
|
||||
#define TAG_H3 13
|
||||
html_h3,
|
||||
#define TAG_H4 15
|
||||
#define TAG_H4 14
|
||||
html_h4,
|
||||
#define TAG_IMG 16
|
||||
#define TAG_IMG 15
|
||||
html_img,
|
||||
#define TAG_INPUT 17
|
||||
#define TAG_INPUT 16
|
||||
html_input,
|
||||
#define TAG_LI 18
|
||||
#define TAG_LI 17
|
||||
html_li,
|
||||
#define TAG_P 19
|
||||
#define TAG_P 18
|
||||
html_p,
|
||||
#define TAG_SCRIPT 20
|
||||
#define TAG_SCRIPT 19
|
||||
html_script,
|
||||
#define TAG_SELECT 21
|
||||
#define TAG_SELECT 20
|
||||
html_select,
|
||||
#define TAG_STYLE 22
|
||||
#define TAG_STYLE 21
|
||||
html_style,
|
||||
#define TAG_TR 23
|
||||
#define TAG_TR 22
|
||||
html_tr,
|
||||
#define TAG_LAST 24
|
||||
#define TAG_LAST 23
|
||||
last,
|
||||
};
|
||||
|
||||
|
@ -254,7 +249,7 @@ htmlparser_init(void)
|
|||
{
|
||||
s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD;
|
||||
s.minorstate = MINORSTATE_TEXT;
|
||||
s.lastchar = 0;
|
||||
s.wordlen = 0;
|
||||
#if WWW_CONF_FORMS
|
||||
s.formaction[0] = 0;
|
||||
#endif /* WWW_CONF_FORMS */
|
||||
|
@ -305,10 +300,10 @@ do_word(void)
|
|||
{
|
||||
if(s.wordlen > 0) {
|
||||
if(s.majorstate == MAJORSTATE_LINK) {
|
||||
if(s.word[s.wordlen] != ISO_space) {
|
||||
if(s.word[s.wordlen - 1] != ISO_space) {
|
||||
add_char(ISO_space);
|
||||
}
|
||||
} else if(s.majorstate == MAJORSTATE_DISCARD) {
|
||||
} else if(s.majorstate >= MAJORSTATE_DISCARD) {
|
||||
s.wordlen = 0;
|
||||
} else {
|
||||
s.word[s.wordlen] = '\0';
|
||||
|
@ -368,13 +363,19 @@ static void
|
|||
parse_tag(void)
|
||||
{
|
||||
static char *tagattrparam;
|
||||
static unsigned char tag;
|
||||
static unsigned char size;
|
||||
|
||||
static char dummy;
|
||||
tag = find_tag(s.tag);
|
||||
/* If we are inside a <script> we mustn't interpret any tags
|
||||
(inside JavaScript strings) but wait for the </script>. */
|
||||
if(s.majorstate == MAJORSTATE_SCRIPT && tag != TAG_SLASHSCRIPT) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRINTF(("Parsing tag '%s' '%s' '%s'\n", s.tag, s.tagattr, s.tagattrparam));
|
||||
|
||||
switch(find_tag(s.tag)) {
|
||||
switch(tag) {
|
||||
case TAG_P:
|
||||
case TAG_H1:
|
||||
case TAG_H2:
|
||||
|
@ -386,15 +387,18 @@ parse_tag(void)
|
|||
case TAG_TR:
|
||||
case TAG_SLASHDIV:
|
||||
case TAG_SLASHH:
|
||||
dummy = 0;
|
||||
newline();
|
||||
break;
|
||||
case TAG_LI:
|
||||
if(s.tagattr[0] == 0) {
|
||||
newline();
|
||||
add_char(ISO_asterisk);
|
||||
add_char(ISO_space);
|
||||
}
|
||||
break;
|
||||
case TAG_SCRIPT:
|
||||
switch_majorstate(MAJORSTATE_SCRIPT);
|
||||
break;
|
||||
case TAG_STYLE:
|
||||
case TAG_SELECT:
|
||||
switch_majorstate(MAJORSTATE_DISCARD);
|
||||
|
@ -408,18 +412,6 @@ parse_tag(void)
|
|||
case TAG_BODY:
|
||||
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
|
||||
break;
|
||||
case TAG_FRAME:
|
||||
if(strncmp(s.tagattr, html_src, sizeof(html_src)) == 0 && s.tagattrparam[0] != 0) {
|
||||
switch_majorstate(MAJORSTATE_BODY);
|
||||
newline();
|
||||
add_char(ISO_rbrack);
|
||||
do_word();
|
||||
htmlparser_link((char *)html_frame, (unsigned char)strlen(html_frame), s.tagattrparam);
|
||||
PRINTF(("Frame [%s]\n", s.tagattrparam));
|
||||
add_char(ISO_lbrack);
|
||||
newline();
|
||||
}
|
||||
break;
|
||||
case TAG_IMG:
|
||||
if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) {
|
||||
add_char(ISO_lt);
|
||||
|
@ -572,6 +564,15 @@ parse_word(char *data, uint8_t dlen)
|
|||
}
|
||||
break;
|
||||
case MINORSTATE_TAG:
|
||||
/* If we are inside a <srcipt> we mustn't mistake a JavaScript
|
||||
equation with a '<' as a tag. So we check for the very next
|
||||
character to be a '/' as we're only interested in parsing
|
||||
the </script>. */
|
||||
if(s.majorstate == MAJORSTATE_SCRIPT && data[0] != ISO_slash) {
|
||||
s.minorstate = MINORSTATE_TEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We are currently parsing within the name of a tag. We check
|
||||
for the end of a tag (the '>' character) or whitespace (which
|
||||
indicates that we should parse a tag attr argument
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
http_http "http://"
|
||||
http_https "https://"
|
||||
http_200 "200 "
|
||||
http_301 "301 "
|
||||
http_302 "302 "
|
||||
|
@ -10,3 +11,4 @@ http_location "location: "
|
|||
http_host "Host: "
|
||||
http_crnl "\r\n"
|
||||
http_html ".html"
|
||||
http_redirect "<body>Redirect to "
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
const char http_http[8] =
|
||||
/* "http://" */
|
||||
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
||||
const char http_https[9] =
|
||||
/* "https://" */
|
||||
{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, };
|
||||
const char http_200[5] =
|
||||
/* "200 " */
|
||||
{0x32, 0x30, 0x30, 0x20, };
|
||||
|
@ -34,3 +37,6 @@ const char http_crnl[3] =
|
|||
const char http_html[6] =
|
||||
/* ".html" */
|
||||
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
|
||||
const char http_redirect[19] =
|
||||
/* "<body>Redirect to " */
|
||||
{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, };
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extern const char http_http[8];
|
||||
extern const char http_https[9];
|
||||
extern const char http_200[5];
|
||||
extern const char http_301[5];
|
||||
extern const char http_302[5];
|
||||
|
@ -10,3 +11,4 @@ extern const char http_location[11];
|
|||
extern const char http_host[7];
|
||||
extern const char http_crnl[3];
|
||||
extern const char http_html[6];
|
||||
extern const char http_redirect[19];
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define HTTPFLAG_NONE 0
|
||||
#define HTTPFLAG_OK 1
|
||||
#define HTTPFLAG_MOVED 2
|
||||
#define HTTPFLAG_ERROR 3
|
||||
#define HTTPFLAG_HTTPS 3
|
||||
|
||||
|
||||
#define ISO_nl 0x0a
|
||||
|
@ -63,11 +63,11 @@ struct webclient_state {
|
|||
|
||||
uint16_t port;
|
||||
char host[40];
|
||||
char file[WWW_CONF_MAX_URLLEN];
|
||||
char file[WWW_CONF_MAX_URLLEN - 10]; // URL - "http://<host>/"
|
||||
uint16_t getrequestptr;
|
||||
uint16_t getrequestleft;
|
||||
|
||||
char httpheaderline[200];
|
||||
char httpheaderline[WWW_CONF_MAX_URLLEN + 10]; // URL + "Location: "
|
||||
uint16_t httpheaderlineptr;
|
||||
|
||||
char mimetype[32];
|
||||
|
@ -327,13 +327,12 @@ parse_headers(uint16_t len)
|
|||
char *cptr;
|
||||
static unsigned char i;
|
||||
|
||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
|
||||
while(len > 0) {
|
||||
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
|
||||
uip_appdata = (char *)uip_appdata + 1;
|
||||
--len;
|
||||
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
|
||||
/* We have an entire HTTP header line in s.httpheaderline, so
|
||||
we parse it. */
|
||||
/* We reached the end of an HTTP header line. */
|
||||
if(s.httpheaderline[0] == ISO_cr) {
|
||||
/* This was the last header line (i.e., and empty "\r\n"), so
|
||||
we are done with the headers and proceed with the actual
|
||||
|
@ -342,6 +341,9 @@ parse_headers(uint16_t len)
|
|||
return len;
|
||||
}
|
||||
|
||||
if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
|
||||
/* We have an entire HTTP header line in s.httpheaderline, so
|
||||
we parse it. */
|
||||
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
|
||||
/* Check for specific HTTP header fields. */
|
||||
if(casecmp(s.httpheaderline, http_content_type,
|
||||
|
@ -358,7 +360,9 @@ parse_headers(uint16_t len)
|
|||
cptr = s.httpheaderline +
|
||||
sizeof(http_location) - 1;
|
||||
|
||||
if(strncmp(cptr, http_http, 7) == 0) {
|
||||
if(strncmp(cptr, http_https, sizeof(http_https) - 1) == 0) {
|
||||
s.httpflag = HTTPFLAG_HTTPS;
|
||||
} else if(strncmp(cptr, http_http, 7) == 0) {
|
||||
cptr += 7;
|
||||
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
|
||||
if(*cptr == 0 ||
|
||||
|
@ -375,15 +379,17 @@ parse_headers(uint16_t len)
|
|||
strncpy(s.file, cptr, sizeof(s.file));
|
||||
/* s.file[s.httpheaderlineptr - i] = 0;*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* We're done parsing, so we reset the pointer and start the
|
||||
next line. */
|
||||
s.httpheaderlineptr = 0;
|
||||
} else {
|
||||
if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
|
||||
++s.httpheaderlineptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -403,7 +409,7 @@ newdata(void)
|
|||
}
|
||||
|
||||
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
||||
s.httpflag != HTTPFLAG_MOVED) {
|
||||
s.httpflag == HTTPFLAG_OK) {
|
||||
webclient_datahandler((char *)uip_appdata, len);
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +447,6 @@ webclient_appcall(void *state)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/* The acked() and newdata() functions may alter the uip_appdata
|
||||
ptr, so we need to store it in the "dataptr" variable so that we
|
||||
can restore it before the senddata() function is called. */
|
||||
|
@ -474,10 +479,18 @@ webclient_appcall(void *state)
|
|||
|
||||
if(uip_closed()) {
|
||||
tcp_markconn(uip_conn, NULL);
|
||||
if(s.httpflag != HTTPFLAG_MOVED) {
|
||||
switch(s.httpflag) {
|
||||
case HTTPFLAG_HTTPS:
|
||||
/* Send some info to the user. */
|
||||
webclient_datahandler((char *)http_redirect, sizeof(http_redirect) - 1);
|
||||
webclient_datahandler(s.file, strlen(s.file));
|
||||
webclient_datahandler((char *)http_crnl, sizeof(http_crnl) - 1);
|
||||
/* FALLTHROUGH */
|
||||
case HTTPFLAG_OK:
|
||||
/* Send NULL data to signal EOF. */
|
||||
webclient_datahandler(NULL, 0);
|
||||
} else {
|
||||
break;
|
||||
case HTTPFLAG_MOVED:
|
||||
/* conn = uip_connect(uip_conn->ripaddr, s.port);
|
||||
if(conn != NULL) {
|
||||
dispatcher_markconn(conn, NULL);
|
||||
|
@ -489,6 +502,7 @@ webclient_appcall(void *state)
|
|||
}
|
||||
#endif /* UIP_UDP */
|
||||
webclient_get(s.host, s.port, s.file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ static struct ctk_button wgetyesbutton =
|
|||
#if WWW_CONF_HISTORY_SIZE > 0
|
||||
/* The char arrays that hold the history of visited URLs. */
|
||||
static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];
|
||||
static char history_last;
|
||||
static unsigned char history_last;
|
||||
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
||||
|
||||
struct linkattrib {
|
||||
|
@ -170,6 +170,7 @@ static struct inputattrib *currptr;
|
|||
|
||||
#define ISO_nl 0x0a
|
||||
#define ISO_space 0x20
|
||||
#define ISO_hash 0x23
|
||||
#define ISO_ampersand 0x26
|
||||
#define ISO_plus 0x2b
|
||||
#define ISO_slash 0x2f
|
||||
|
@ -181,6 +182,7 @@ static char *webpageptr;
|
|||
static unsigned char x, y;
|
||||
static unsigned char loading;
|
||||
static unsigned short firsty, pagey;
|
||||
static unsigned char newlines;
|
||||
|
||||
static unsigned char count;
|
||||
static char receivingmsgs[4][23] = {
|
||||
|
@ -194,7 +196,7 @@ PROCESS(www_process, "Web browser");
|
|||
|
||||
AUTOSTART_PROCESSES(&www_process);
|
||||
|
||||
static void CC_FASTCALL formsubmit(struct formattrib *form);
|
||||
static void CC_FASTCALL formsubmit(struct inputattrib *trigger);
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* make_window()
|
||||
|
@ -277,6 +279,7 @@ start_loading(void)
|
|||
loading = 1;
|
||||
x = y = 0;
|
||||
pagey = 0;
|
||||
newlines = 0;
|
||||
webpageptr = webpage;
|
||||
|
||||
clear_page();
|
||||
|
@ -305,10 +308,13 @@ open_url(void)
|
|||
static uip_ipaddr_t addr;
|
||||
|
||||
/* Trim off any spaces in the end of the url. */
|
||||
urlptr = url + strlen(url) - 1;
|
||||
while(*urlptr == ' ' && urlptr > url) {
|
||||
*urlptr = 0;
|
||||
--urlptr;
|
||||
urlptr = url + strlen(url);
|
||||
while(urlptr > url) {
|
||||
if(*(urlptr - 1) == ' ') {
|
||||
*--urlptr = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't even try to go further if the URL is empty. */
|
||||
|
@ -376,7 +382,6 @@ open_url(void)
|
|||
} else {
|
||||
show_statustext("Connecting...");
|
||||
}
|
||||
redraw_window();
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* set_link(link):
|
||||
|
@ -510,15 +515,17 @@ PROCESS_THREAD(www_process, ev, data)
|
|||
firsty = 0;
|
||||
start_loading();
|
||||
--history_last;
|
||||
/* Note: history_last is unsigned ! */
|
||||
if(history_last > WWW_CONF_HISTORY_SIZE) {
|
||||
history_last = WWW_CONF_HISTORY_SIZE - 1;
|
||||
}
|
||||
memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN);
|
||||
*history[(int)history_last] = 0;
|
||||
open_url();
|
||||
CTK_WIDGET_FOCUS(&mainwindow, &backbutton);
|
||||
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
||||
} else if(w == (struct ctk_widget *)&downbutton) {
|
||||
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4;
|
||||
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 2;
|
||||
start_loading();
|
||||
open_url();
|
||||
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
|
||||
|
@ -557,9 +564,8 @@ PROCESS_THREAD(www_process, ev, data)
|
|||
#if WWW_CONF_FORMS
|
||||
} else {
|
||||
/* Assume form widget. */
|
||||
struct inputattrib *input = (struct inputattrib *)
|
||||
(((char *)w) - offsetof(struct inputattrib, widget));
|
||||
formsubmit(input->formptr);
|
||||
formsubmit((struct inputattrib *)
|
||||
(((char *)w) - offsetof(struct inputattrib, widget)));
|
||||
#endif /* WWW_CONF_FORMS */
|
||||
}
|
||||
} else if(ev == ctk_signal_hyperlink_activate) {
|
||||
|
@ -670,8 +676,6 @@ webclient_connected(void)
|
|||
{
|
||||
start_loading();
|
||||
|
||||
clear_page();
|
||||
|
||||
show_statustext("Request sent...");
|
||||
set_url(webclient_hostname(), webclient_port(), webclient_filename());
|
||||
|
||||
|
@ -731,6 +735,8 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
|
|||
char *wptr;
|
||||
static unsigned char maxwidth;
|
||||
|
||||
newlines = 0;
|
||||
|
||||
if(!loading) {
|
||||
return;
|
||||
}
|
||||
|
@ -804,6 +810,7 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
|
|||
textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
|
||||
add_forminput((struct inputattrib *)textptr);
|
||||
textptr->formptr = formptr;
|
||||
petsciiconv_topetscii(text, strlen(text));
|
||||
strcpy(textptr->textentry.text, text);
|
||||
strcpy(textptr->name, attrib);
|
||||
if(size) {
|
||||
|
@ -837,6 +844,10 @@ htmlparser_newline(void)
|
|||
{
|
||||
char *wptr;
|
||||
|
||||
if(++newlines > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(pagey < firsty) {
|
||||
++pagey;
|
||||
x = 0;
|
||||
|
@ -863,6 +874,8 @@ htmlparser_newline(void)
|
|||
void
|
||||
htmlparser_word(char *word, unsigned char wordlen)
|
||||
{
|
||||
newlines = 0;
|
||||
|
||||
if(loading) {
|
||||
if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
|
||||
htmlparser_newline();
|
||||
|
@ -886,8 +899,13 @@ htmlparser_word(char *word, unsigned char wordlen)
|
|||
void
|
||||
htmlparser_link(char *text, unsigned char textlen, char *url)
|
||||
{
|
||||
/* No link for https or fragment-only as we would't be able to handle it anyway. */
|
||||
if(url[0] == ISO_hash || strncmp(url, http_https, sizeof(http_https) - 1) == 0) {
|
||||
htmlparser_word(text, textlen);
|
||||
} else {
|
||||
add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if WWW_CONF_FORMS
|
||||
void
|
||||
|
@ -946,23 +964,36 @@ add_query(char delimiter, char *string)
|
|||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void CC_FASTCALL
|
||||
formsubmit(struct formattrib *form)
|
||||
formsubmit(struct inputattrib *trigger)
|
||||
{
|
||||
struct inputattrib *inputptr;
|
||||
struct inputattrib *input;
|
||||
struct formattrib *form = trigger->formptr;
|
||||
char delimiter = ISO_questionmark;
|
||||
|
||||
set_link(form->action);
|
||||
|
||||
for(inputptr = form->nextptr; inputptr != NULL; inputptr = inputptr->nextptr) {
|
||||
/* No button pressed so prepare to look for default button. */
|
||||
if(trigger->widget.type == CTK_WIDGET_TEXTENTRY) {
|
||||
trigger = NULL;
|
||||
}
|
||||
|
||||
for(input = form->nextptr; input != NULL; input = input->nextptr) {
|
||||
char *name;
|
||||
char *value;
|
||||
|
||||
if(inputptr->widget.type == CTK_WIDGET_BUTTON) {
|
||||
name = ((struct submitattrib *)inputptr)->name;
|
||||
value = ((struct submitattrib *)inputptr)->button.text;
|
||||
if(input->widget.type == CTK_WIDGET_TEXTENTRY) {
|
||||
name = ((struct textattrib *)input)->name;
|
||||
value = ((struct textattrib *)input)->textentry.text;
|
||||
} else {
|
||||
name = ((struct textattrib *)inputptr)->name;
|
||||
value = ((struct textattrib *)inputptr)->textentry.text;
|
||||
/* Consider first button as default button. */
|
||||
if(trigger == NULL) {
|
||||
trigger = input;
|
||||
}
|
||||
if(input != trigger) {
|
||||
continue;
|
||||
}
|
||||
name = ((struct submitattrib *)input)->name;
|
||||
value = ((struct submitattrib *)input)->button.text;
|
||||
}
|
||||
|
||||
add_query(delimiter, name);
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define WWW_CONF_HISTORY_SIZE 10
|
||||
#endif
|
||||
#ifndef WWW_CONF_MAX_URLLEN
|
||||
#define WWW_CONF_MAX_URLLEN 300
|
||||
#define WWW_CONF_MAX_URLLEN 255
|
||||
#endif
|
||||
#ifndef WWW_CONF_PAGEATTRIB_SIZE
|
||||
#define WWW_CONF_PAGEATTRIB_SIZE 2000
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
http_http "http://"
|
||||
http_https "https://"
|
||||
http_200 "200 "
|
||||
http_301 "301 "
|
||||
http_302 "302 "
|
||||
|
@ -32,4 +33,4 @@ http_gif ".gif"
|
|||
http_jpg ".jpg"
|
||||
http_text ".text"
|
||||
http_txt ".txt"
|
||||
|
||||
http_redirect "<body>Redirect to "
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
const char http_http[8] =
|
||||
/* "http://" */
|
||||
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
||||
const char http_https[9] =
|
||||
/* "https://" */
|
||||
{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, };
|
||||
const char http_200[5] =
|
||||
/* "200 " */
|
||||
{0x32, 0x30, 0x30, 0x20, };
|
||||
|
@ -100,3 +103,6 @@ const char http_text[6] =
|
|||
const char http_txt[5] =
|
||||
/* ".txt" */
|
||||
{0x2e, 0x74, 0x78, 0x74, };
|
||||
const char http_redirect[19] =
|
||||
/* "<body>Redirect to " */
|
||||
{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, };
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extern const char http_http[8];
|
||||
extern const char http_https[9];
|
||||
extern const char http_200[5];
|
||||
extern const char http_301[5];
|
||||
extern const char http_302[5];
|
||||
|
@ -32,3 +33,4 @@ extern const char http_gif[5];
|
|||
extern const char http_jpg[5];
|
||||
extern const char http_text[6];
|
||||
extern const char http_txt[5];
|
||||
extern const char http_redirect[19];
|
||||
|
|
|
@ -80,7 +80,7 @@ galois_mul2(uint8_t value)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_key(uint8_t *key)
|
||||
set_key(const uint8_t *key)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
|
|
|
@ -59,7 +59,7 @@ struct aes_128_driver {
|
|||
/**
|
||||
* \brief Sets the current key.
|
||||
*/
|
||||
void (* set_key)(uint8_t *key);
|
||||
void (* set_key)(const uint8_t *key);
|
||||
|
||||
/**
|
||||
* \brief Encrypts.
|
||||
|
|
|
@ -34,44 +34,37 @@
|
|||
* \file
|
||||
* AES_128-based CCM* implementation.
|
||||
* \author
|
||||
* Konrad Krentz <konrad.krentz@gmail.com>
|
||||
* Original: Konrad Krentz <konrad.krentz@gmail.com>
|
||||
* Generified version: Justin King-Lacroix <justin.kinglacroix@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup llsec802154
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "net/llsec/ccm-star.h"
|
||||
#include "net/llsec/llsec802154.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "ccm-star.h"
|
||||
#include "lib/aes-128.h"
|
||||
#include <string.h>
|
||||
|
||||
/* see RFC 3610 */
|
||||
#define CCM_STAR_AUTH_FLAGS(Adata, M) ((Adata ? (1u << 6) : 0) | (((M - 2u) >> 1) << 3) | 1u)
|
||||
#define CCM_STAR_ENCRYPTION_FLAGS 1
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_nonce(uint8_t *nonce,
|
||||
set_nonce(uint8_t *iv,
|
||||
uint8_t flags,
|
||||
const uint8_t *extended_source_address,
|
||||
const uint8_t *nonce,
|
||||
uint8_t counter)
|
||||
{
|
||||
/* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */
|
||||
/* flags || extended_source_address || frame_counter || sec_lvl || counter */
|
||||
|
||||
nonce[0] = flags;
|
||||
memcpy(nonce + 1, extended_source_address, 8);
|
||||
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
|
||||
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
|
||||
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
|
||||
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
|
||||
nonce[13] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
|
||||
nonce[14] = 0;
|
||||
nonce[15] = counter;
|
||||
iv[0] = flags;
|
||||
memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH);
|
||||
iv[14] = 0;
|
||||
iv[15] = counter;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */
|
||||
static void
|
||||
ctr_step(const uint8_t *extended_source_address,
|
||||
ctr_step(const uint8_t *nonce,
|
||||
uint8_t pos,
|
||||
uint8_t *m_and_result,
|
||||
uint8_t m_len,
|
||||
|
@ -80,7 +73,7 @@ ctr_step(const uint8_t *extended_source_address,
|
|||
uint8_t a[AES_128_BLOCK_SIZE];
|
||||
uint8_t i;
|
||||
|
||||
set_nonce(a, CCM_STAR_ENCRYPTION_FLAGS, extended_source_address, counter);
|
||||
set_nonce(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter);
|
||||
AES_128.encrypt(a);
|
||||
|
||||
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
|
||||
|
@ -89,43 +82,20 @@ ctr_step(const uint8_t *extended_source_address,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mic(const uint8_t *extended_source_address,
|
||||
mic(const uint8_t *m, uint8_t m_len,
|
||||
const uint8_t *nonce,
|
||||
const uint8_t *a, uint8_t a_len,
|
||||
uint8_t *result,
|
||||
uint8_t mic_len)
|
||||
{
|
||||
uint8_t x[AES_128_BLOCK_SIZE];
|
||||
uint8_t pos;
|
||||
uint8_t i;
|
||||
uint8_t a_len;
|
||||
uint8_t *a;
|
||||
#if LLSEC802154_USES_ENCRYPTION
|
||||
uint8_t shall_encrypt;
|
||||
uint8_t m_len;
|
||||
uint8_t *m;
|
||||
|
||||
shall_encrypt = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2);
|
||||
if(shall_encrypt) {
|
||||
a_len = packetbuf_hdrlen();
|
||||
m_len = packetbuf_datalen();
|
||||
} else {
|
||||
a_len = packetbuf_totlen();
|
||||
m_len = 0;
|
||||
}
|
||||
set_nonce(x,
|
||||
CCM_STAR_AUTH_FLAGS(a_len, mic_len),
|
||||
extended_source_address,
|
||||
m_len);
|
||||
#else /* LLSEC802154_USES_ENCRYPTION */
|
||||
a_len = packetbuf_totlen();
|
||||
set_nonce(x,
|
||||
CCM_STAR_AUTH_FLAGS(a_len, mic_len),
|
||||
extended_source_address,
|
||||
0);
|
||||
#endif /* LLSEC802154_USES_ENCRYPTION */
|
||||
set_nonce(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len);
|
||||
AES_128.encrypt(x);
|
||||
|
||||
a = packetbuf_hdrptr();
|
||||
if(a_len) {
|
||||
if(a_len > 0) {
|
||||
x[1] = x[1] ^ a_len;
|
||||
for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
|
||||
x[i] ^= a[i - 2];
|
||||
|
@ -143,8 +113,7 @@ mic(const uint8_t *extended_source_address,
|
|||
}
|
||||
}
|
||||
|
||||
#if LLSEC802154_USES_ENCRYPTION
|
||||
if(shall_encrypt) {
|
||||
if(m_len > 0) {
|
||||
m = a + a_len;
|
||||
pos = 0;
|
||||
while(pos < m_len) {
|
||||
|
@ -155,36 +124,33 @@ mic(const uint8_t *extended_source_address,
|
|||
AES_128.encrypt(x);
|
||||
}
|
||||
}
|
||||
#endif /* LLSEC802154_USES_ENCRYPTION */
|
||||
|
||||
ctr_step(extended_source_address, 0, x, AES_128_BLOCK_SIZE, 0);
|
||||
ctr_step(nonce, 0, x, AES_128_BLOCK_SIZE, 0);
|
||||
|
||||
memcpy(result, x, mic_len);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
ctr(const uint8_t *extended_source_address)
|
||||
ctr(uint8_t *m, uint8_t m_len, const uint8_t* nonce)
|
||||
{
|
||||
uint8_t m_len;
|
||||
uint8_t *m;
|
||||
uint8_t pos;
|
||||
uint8_t counter;
|
||||
|
||||
m_len = packetbuf_datalen();
|
||||
m = (uint8_t *) packetbuf_dataptr();
|
||||
|
||||
pos = 0;
|
||||
counter = 1;
|
||||
while(pos < m_len) {
|
||||
ctr_step(extended_source_address, pos, m, m_len, counter++);
|
||||
ctr_step(nonce, pos, m, m_len, counter++);
|
||||
pos += AES_128_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void set_key(const uint8_t *key) {
|
||||
AES_128.set_key((uint8_t*)key);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct ccm_star_driver ccm_star_driver = {
|
||||
mic,
|
||||
ctr
|
||||
ctr,
|
||||
set_key
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
|
@ -34,23 +34,13 @@
|
|||
* \file
|
||||
* CCM* header file.
|
||||
* \author
|
||||
* Konrad Krentz <konrad.krentz@gmail.com>
|
||||
* Original: Konrad Krentz <konrad.krentz@gmail.com>
|
||||
* Generified version: Justin King-Lacroix <justin.kinglacroix@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup llsec802154
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef CCM_STAR_H_
|
||||
#define CCM_STAR_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/mac/frame802154.h"
|
||||
|
||||
/* see RFC 3610 */
|
||||
#define CCM_STAR_AUTH_FLAGS(Adata, M) ((Adata ? (1 << 6) : 0) | (((M - 2) >> 1) << 3) | 1)
|
||||
#define CCM_STAR_ENCRYPTION_FLAGS 1
|
||||
|
||||
#ifdef CCM_STAR_CONF
|
||||
#define CCM_STAR CCM_STAR_CONF
|
||||
|
@ -58,28 +48,43 @@
|
|||
#define CCM_STAR ccm_star_driver
|
||||
#endif /* CCM_STAR_CONF */
|
||||
|
||||
#define CCM_STAR_NONCE_LENGTH 13
|
||||
|
||||
/**
|
||||
* Structure of CCM* drivers.
|
||||
*/
|
||||
struct ccm_star_driver {
|
||||
|
||||
/**
|
||||
* \brief Generates a MIC over the frame in the packetbuf.
|
||||
* \brief Generates a MIC over the data supplied.
|
||||
* \param data The data buffer to read.
|
||||
* \param data_length The data buffer length.
|
||||
* \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long.
|
||||
* \param result The generated MIC will be put here
|
||||
* \param mic_len <= 16; set to LLSEC802154_MIC_LENGTH to be compliant
|
||||
* \param mic_len The size of the MIC to be generated. <= 16.
|
||||
*/
|
||||
void (* mic)(const uint8_t *extended_source_address,
|
||||
void (* mic)(const uint8_t* data, uint8_t data_length,
|
||||
const uint8_t* nonce,
|
||||
const uint8_t* add, uint8_t add_len,
|
||||
uint8_t *result,
|
||||
uint8_t mic_len);
|
||||
|
||||
/**
|
||||
* \brief XORs the frame in the packetbuf with the key stream.
|
||||
* \param data The data buffer to read.
|
||||
* \param data_length The data buffer length.
|
||||
* \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long.
|
||||
*/
|
||||
void (* ctr)(const uint8_t *extended_source_address);
|
||||
void (* ctr)( uint8_t* data, uint8_t data_length,
|
||||
const uint8_t* nonce);
|
||||
|
||||
/**
|
||||
* \brief Sets the key in use. Default implementation calls AES_128.set_key()
|
||||
* \param key The key to use.
|
||||
*/
|
||||
void (* set_key)(const uint8_t* key);
|
||||
};
|
||||
|
||||
extern const struct ccm_star_driver CCM_STAR;
|
||||
|
||||
#endif /* CCM_STAR_H_ */
|
||||
|
||||
/** @} */
|
|
@ -300,7 +300,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
}
|
||||
|
||||
selecting:
|
||||
xid++;
|
||||
s.ticks = CLOCK_SECOND;
|
||||
do {
|
||||
while(ev != tcpip_event) {
|
||||
|
@ -366,7 +365,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
}
|
||||
|
||||
/* renewing: */
|
||||
xid++;
|
||||
do {
|
||||
while(ev != tcpip_event) {
|
||||
tcpip_poll_udp(s.conn);
|
||||
|
|
|
@ -394,7 +394,7 @@ dns_name_isequal(const unsigned char *queryptr, const char *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(tolower(*name++) != tolower(*queryptr++)) {
|
||||
if(tolower((unsigned int)*name++) != tolower((unsigned int)*queryptr++)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,14 +43,16 @@
|
|||
void
|
||||
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
||||
{
|
||||
if(addr == NULL || addr->u8 == NULL) {
|
||||
printf("(NULL IP addr)");
|
||||
return;
|
||||
}
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uint16_t a;
|
||||
unsigned int i;
|
||||
int f;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
if(addr == NULL) {
|
||||
PRINTA("(NULL IP addr)");
|
||||
return;
|
||||
}
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
|
||||
a = (addr->u8[i] << 8) + addr->u8[i + 1];
|
||||
if(a == 0 && f >= 0) {
|
||||
|
@ -75,6 +77,10 @@ void
|
|||
uip_debug_lladdr_print(const uip_lladdr_t *addr)
|
||||
{
|
||||
unsigned int i;
|
||||
if(addr == NULL) {
|
||||
PRINTA("(NULL LL addr)");
|
||||
return;
|
||||
}
|
||||
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
|
||||
if(i > 0) {
|
||||
PRINTA(":");
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct uip_nameserver_record {
|
|||
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||
/** \brief Initialization flag */
|
||||
static uint8_t initialized = 0;
|
||||
#endif
|
||||
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||
|
||||
/** \name List and memory block
|
||||
* @{
|
||||
|
@ -92,7 +92,7 @@ init(void)
|
|||
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime)
|
||||
uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime)
|
||||
{
|
||||
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||
register uip_nameserver_record *e;
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
* considered to remove an entry. Maximum is 0xFFFFFFFF which
|
||||
* is considered infinite.
|
||||
*/
|
||||
void uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime);
|
||||
void uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime);
|
||||
|
||||
/**
|
||||
* \brief Get a Nameserver ip address given in RA
|
||||
|
|
|
@ -308,7 +308,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
}
|
||||
|
||||
selecting:
|
||||
xid++;
|
||||
s.ticks = CLOCK_SECOND;
|
||||
do {
|
||||
while(ev != tcpip_event) {
|
||||
|
@ -374,7 +373,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
}
|
||||
|
||||
/* renewing: */
|
||||
xid++;
|
||||
do {
|
||||
while(ev != tcpip_event) {
|
||||
tcpip_poll_udp(s.conn);
|
||||
|
|
|
@ -1107,26 +1107,26 @@ icmp_input()
|
|||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
PRINTF("\n");
|
||||
ROLL_TM_STATS_ADD(icmp_bad);
|
||||
return;
|
||||
goto discard;
|
||||
}
|
||||
|
||||
if(!uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr)
|
||||
&& !uip_is_addr_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||
PRINTF("ROLL TM: ICMPv6 In, bad destination\n");
|
||||
ROLL_TM_STATS_ADD(icmp_bad);
|
||||
return;
|
||||
goto discard;
|
||||
}
|
||||
|
||||
if(UIP_ICMP_BUF->icode != ROLL_TM_ICMP_CODE) {
|
||||
PRINTF("ROLL TM: ICMPv6 In, bad ICMP code\n");
|
||||
ROLL_TM_STATS_ADD(icmp_bad);
|
||||
return;
|
||||
goto discard;
|
||||
}
|
||||
|
||||
if(UIP_IP_BUF->ttl != ROLL_TM_IP_HOP_LIMIT) {
|
||||
PRINTF("ROLL TM: ICMPv6 In, bad TTL\n");
|
||||
ROLL_TM_STATS_ADD(icmp_bad);
|
||||
return;
|
||||
goto discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1311,6 +1311,9 @@ drop:
|
|||
t[1].c++;
|
||||
}
|
||||
|
||||
discard:
|
||||
|
||||
uip_len = 0;
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
52
core/net/llsec/ccm-star-packetbuf.c
Normal file
52
core/net/llsec/ccm-star-packetbuf.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* \file
|
||||
* CCM* convenience functions for LLSEC use
|
||||
* \author
|
||||
* Justin King-Lacroix <justin.kinglacroix@gmail.com>
|
||||
*/
|
||||
|
||||
#include "lib/ccm-star.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void ccm_star_mic_packetbuf(const uint8_t *extended_source_address,
|
||||
uint8_t *result,
|
||||
uint8_t mic_len)
|
||||
{
|
||||
uint8_t *dataptr = packetbuf_dataptr();
|
||||
uint8_t data_len = packetbuf_datalen();
|
||||
uint8_t *headerptr = packetbuf_hdrptr();
|
||||
uint8_t header_len = packetbuf_hdrlen();
|
||||
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
|
||||
|
||||
memcpy(nonce, extended_source_address, 8);
|
||||
nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
|
||||
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
|
||||
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
|
||||
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
|
||||
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
|
||||
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2)) {
|
||||
CCM_STAR.mic(dataptr, data_len, nonce, headerptr, header_len, result, mic_len);
|
||||
} else {
|
||||
CCM_STAR.mic(dataptr, 0, nonce, headerptr, packetbuf_totlen(), result, mic_len);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void ccm_star_ctr_packetbuf(const uint8_t *extended_source_address)
|
||||
{
|
||||
uint8_t *dataptr = packetbuf_dataptr();
|
||||
uint8_t data_len = packetbuf_datalen();
|
||||
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
|
||||
|
||||
memcpy(nonce, extended_source_address, 8);
|
||||
nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
|
||||
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
|
||||
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
|
||||
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
|
||||
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
|
||||
|
||||
CCM_STAR.ctr(dataptr, data_len, nonce);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
24
core/net/llsec/ccm-star-packetbuf.h
Normal file
24
core/net/llsec/ccm-star-packetbuf.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* \file
|
||||
* CCM* convenience functions for MAC security
|
||||
* \author
|
||||
* Justin King-Lacroix <justin.kinglacroix@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef CCM_STAR_PACKETBUF_H_
|
||||
#define CCM_STAR_PACKETBUF_H_
|
||||
|
||||
/**
|
||||
* \brief Calls CCM_STAR.mic with parameters appropriate for LLSEC.
|
||||
*/
|
||||
void ccm_star_mic_packetbuf(const uint8_t *extended_source_address,
|
||||
uint8_t *result,
|
||||
uint8_t mic_len);
|
||||
|
||||
/**
|
||||
* \brief Calls CCM_STAR.ctr with parameters appropriate for LLSEC.
|
||||
*/
|
||||
void ccm_star_ctr_packetbuf(const uint8_t *extended_source_address);
|
||||
|
||||
#endif /* CCM_STAR_PACKETBUF_H_ */
|
||||
|
|
@ -45,13 +45,13 @@
|
|||
#include "net/llsec/noncoresec/noncoresec.h"
|
||||
#include "net/llsec/anti-replay.h"
|
||||
#include "net/llsec/llsec802154.h"
|
||||
#include "net/llsec/ccm-star.h"
|
||||
#include "net/llsec/ccm-star-packetbuf.h"
|
||||
#include "net/mac/frame802154.h"
|
||||
#include "net/netstack.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/nbr-table.h"
|
||||
#include "net/linkaddr.h"
|
||||
#include "lib/aes-128.h"
|
||||
#include "lib/ccm-star.h"
|
||||
#include <string.h>
|
||||
|
||||
#define WITH_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2))
|
||||
|
@ -110,15 +110,12 @@ send(mac_callback_t sent, void *ptr)
|
|||
static int
|
||||
on_frame_created(void)
|
||||
{
|
||||
uint8_t *dataptr;
|
||||
uint8_t data_len;
|
||||
uint8_t *dataptr = packetbuf_dataptr();
|
||||
uint8_t data_len = packetbuf_datalen();
|
||||
|
||||
dataptr = packetbuf_dataptr();
|
||||
data_len = packetbuf_datalen();
|
||||
|
||||
CCM_STAR.mic(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH);
|
||||
ccm_star_mic_packetbuf(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH);
|
||||
#if WITH_ENCRYPTION
|
||||
CCM_STAR.ctr(get_extended_address(&linkaddr_node_addr));
|
||||
ccm_star_ctr_packetbuf(get_extended_address(&linkaddr_node_addr));
|
||||
#endif /* WITH_ENCRYPTION */
|
||||
packetbuf_set_datalen(data_len + LLSEC802154_MIC_LENGTH);
|
||||
|
||||
|
@ -132,6 +129,8 @@ input(void)
|
|||
uint8_t *received_mic;
|
||||
const linkaddr_t *sender;
|
||||
struct anti_replay_info* info;
|
||||
uint8_t *dataptr = packetbuf_dataptr();
|
||||
uint8_t data_len = packetbuf_datalen();
|
||||
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) {
|
||||
PRINTF("noncoresec: received frame with wrong security level\n");
|
||||
|
@ -143,14 +142,15 @@ input(void)
|
|||
return;
|
||||
}
|
||||
|
||||
packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH);
|
||||
data_len -= LLSEC802154_MIC_LENGTH;
|
||||
packetbuf_set_datalen(data_len);
|
||||
|
||||
#if WITH_ENCRYPTION
|
||||
CCM_STAR.ctr(get_extended_address(sender));
|
||||
ccm_star_ctr_packetbuf(get_extended_address(sender));
|
||||
#endif /* WITH_ENCRYPTION */
|
||||
CCM_STAR.mic(get_extended_address(sender), generated_mic, LLSEC802154_MIC_LENGTH);
|
||||
ccm_star_mic_packetbuf(get_extended_address(sender), generated_mic, LLSEC802154_MIC_LENGTH);
|
||||
|
||||
received_mic = ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen();
|
||||
received_mic = dataptr + data_len;
|
||||
if(memcmp(generated_mic, received_mic, LLSEC802154_MIC_LENGTH) != 0) {
|
||||
PRINTF("noncoresec: received nonauthentic frame %"PRIu32"\n",
|
||||
anti_replay_get_counter());
|
||||
|
@ -203,7 +203,7 @@ get_overhead(void)
|
|||
static void
|
||||
bootstrap(llsec_on_bootstrapped_t on_bootstrapped)
|
||||
{
|
||||
AES_128.set_key(key);
|
||||
CCM_STAR.set_key(key);
|
||||
nbr_table_register(anti_replay_table, NULL);
|
||||
on_bootstrapped();
|
||||
}
|
||||
|
|
|
@ -136,11 +136,15 @@ static int we_are_receiving_burst = 0;
|
|||
|
||||
/* CCA_SLEEP_TIME is the time between two successive CCA checks. */
|
||||
/* Add 1 when rtimer ticks are coarse */
|
||||
#ifdef CONTIKIMAC_CONF_CCA_SLEEP_TIME
|
||||
#define CCA_SLEEP_TIME CONTIKIMAC_CONF_CCA_SLEEP_TIME
|
||||
#else
|
||||
#if RTIMER_ARCH_SECOND > 8000
|
||||
#define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000
|
||||
#else
|
||||
#define CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 2000) + 1
|
||||
#endif
|
||||
#endif /* RTIMER_ARCH_SECOND > 8000 */
|
||||
#endif /* CONTIKIMAC_CONF_CCA_SLEEP_TIME */
|
||||
|
||||
/* CHECK_TIME is the total time it takes to perform CCA_COUNT_MAX
|
||||
CCAs. */
|
||||
|
@ -153,7 +157,11 @@ static int we_are_receiving_burst = 0;
|
|||
/* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking
|
||||
for activity after a potential packet has been detected by a CCA
|
||||
check. */
|
||||
#ifdef CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED
|
||||
#define LISTEN_TIME_AFTER_PACKET_DETECTED CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED
|
||||
#else
|
||||
#define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80
|
||||
#endif
|
||||
|
||||
/* MAX_SILENCE_PERIODS is the maximum amount of periods (a period is
|
||||
CCA_CHECK_TIME + CCA_SLEEP_TIME) that we allow to be silent before
|
||||
|
@ -195,6 +203,12 @@ static int we_are_receiving_burst = 0;
|
|||
to a neighbor for which we have a phase lock. */
|
||||
#define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60
|
||||
|
||||
#ifdef CONTIKIMAC_CONF_SEND_SW_ACK
|
||||
#define CONTIKIMAC_SEND_SW_ACK CONTIKIMAC_CONF_SEND_SW_ACK
|
||||
#else
|
||||
#define CONTIKIMAC_SEND_SW_ACK 0
|
||||
#endif
|
||||
|
||||
#define ACK_LEN 3
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -490,7 +504,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
int is_receiver_awake)
|
||||
{
|
||||
rtimer_clock_t t0;
|
||||
#if WITH_PHASE_OPTIMIZATION
|
||||
rtimer_clock_t encounter_time = 0;
|
||||
#endif
|
||||
int strobes;
|
||||
uint8_t got_strobe_ack = 0;
|
||||
int len;
|
||||
|
@ -664,7 +680,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
|
||||
{
|
||||
rtimer_clock_t wt;
|
||||
#if WITH_PHASE_OPTIMIZATION
|
||||
rtimer_clock_t txtime = RTIMER_NOW();
|
||||
#endif
|
||||
#if RDC_CONF_HARDWARE_ACK
|
||||
int ret = NETSTACK_RADIO.transmit(transmit_len);
|
||||
#else
|
||||
|
@ -677,7 +695,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
if(ret == RADIO_TX_OK) {
|
||||
if(!is_broadcast) {
|
||||
got_strobe_ack = 1;
|
||||
#if WITH_PHASE_OPTIMIZATION
|
||||
encounter_time = txtime;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
} else if (ret == RADIO_TX_NOACK) {
|
||||
|
@ -702,7 +722,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
|
||||
if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) {
|
||||
got_strobe_ack = 1;
|
||||
#if WITH_PHASE_OPTIMIZATION
|
||||
encounter_time = txtime;
|
||||
#endif
|
||||
break;
|
||||
} else {
|
||||
PRINTF("contikimac: collisions while sending\n");
|
||||
|
@ -861,10 +883,26 @@ static void
|
|||
input_packet(void)
|
||||
{
|
||||
static struct ctimer ct;
|
||||
int duplicate = 0;
|
||||
|
||||
#if CONTIKIMAC_SEND_SW_ACK
|
||||
int original_datalen;
|
||||
uint8_t *original_dataptr;
|
||||
|
||||
original_datalen = packetbuf_datalen();
|
||||
original_dataptr = packetbuf_dataptr();
|
||||
#endif
|
||||
|
||||
if(!we_are_receiving_burst) {
|
||||
off();
|
||||
}
|
||||
|
||||
if(packetbuf_datalen() == ACK_LEN) {
|
||||
/* Ignore ack packets */
|
||||
PRINTF("ContikiMAC: ignored ack\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/
|
||||
|
||||
if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) {
|
||||
|
@ -892,12 +930,13 @@ input_packet(void)
|
|||
|
||||
#if RDC_WITH_DUPLICATE_DETECTION
|
||||
/* Check for duplicate packet. */
|
||||
if(mac_sequence_is_duplicate()) {
|
||||
duplicate = mac_sequence_is_duplicate();
|
||||
if(duplicate) {
|
||||
/* Drop the packet. */
|
||||
/* printf("Drop duplicate ContikiMAC layer packet\n");*/
|
||||
return;
|
||||
}
|
||||
PRINTF("contikimac: Drop duplicate\n");
|
||||
} else {
|
||||
mac_sequence_register_seqno();
|
||||
}
|
||||
#endif /* RDC_WITH_DUPLICATE_DETECTION */
|
||||
|
||||
#if CONTIKIMAC_CONF_COMPOWER
|
||||
|
@ -915,7 +954,30 @@ input_packet(void)
|
|||
#endif /* CONTIKIMAC_CONF_COMPOWER */
|
||||
|
||||
PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen());
|
||||
|
||||
#if CONTIKIMAC_SEND_SW_ACK
|
||||
{
|
||||
frame802154_t info154;
|
||||
frame802154_parse(original_dataptr, original_datalen, &info154);
|
||||
if(info154.fcf.frame_type == FRAME802154_DATAFRAME &&
|
||||
info154.fcf.ack_required != 0 &&
|
||||
linkaddr_cmp((linkaddr_t *)&info154.dest_addr,
|
||||
&linkaddr_node_addr)) {
|
||||
uint8_t ackdata[ACK_LEN] = {0, 0, 0};
|
||||
|
||||
we_are_sending = 1;
|
||||
ackdata[0] = FRAME802154_ACKFRAME;
|
||||
ackdata[1] = 0;
|
||||
ackdata[2] = info154.seq;
|
||||
NETSTACK_RADIO.send(ackdata, ACK_LEN);
|
||||
we_are_sending = 0;
|
||||
}
|
||||
}
|
||||
#endif /* CONTIKIMAC_SEND_SW_ACK */
|
||||
|
||||
if(!duplicate) {
|
||||
NETSTACK_MAC.input();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
PRINTDEBUG("contikimac: data not for us\n");
|
||||
|
|
|
@ -254,13 +254,11 @@ collect_neighbor_list_remove(struct collect_neighbor_list *neighbors_list,
|
|||
struct collect_neighbor *
|
||||
collect_neighbor_list_best(struct collect_neighbor_list *neighbors_list)
|
||||
{
|
||||
int found;
|
||||
struct collect_neighbor *n, *best;
|
||||
uint16_t rtmetric;
|
||||
|
||||
rtmetric = RTMETRIC_MAX;
|
||||
best = NULL;
|
||||
found = 0;
|
||||
|
||||
if(neighbors_list == NULL) {
|
||||
return NULL;
|
||||
|
|
|
@ -950,14 +950,18 @@ node_packet_received(struct unicast_conn *c, const linkaddr_t *from)
|
|||
if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
|
||||
PACKETBUF_ATTR_PACKET_TYPE_DATA) {
|
||||
linkaddr_t ack_to;
|
||||
#if DEBUG
|
||||
uint8_t packet_seqno;
|
||||
#endif
|
||||
|
||||
stats.datarecv++;
|
||||
|
||||
/* Remember to whom we should send the ACK, since we reuse the
|
||||
packet buffer and its attributes when sending the ACK. */
|
||||
linkaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
#if DEBUG
|
||||
packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
|
||||
#endif
|
||||
|
||||
/* If the queue is more than half filled, we add the CONGESTED
|
||||
flag to our outgoing acks. */
|
||||
|
|
|
@ -105,6 +105,22 @@
|
|||
#define RPL_MAX_DAG_PER_INSTANCE 2
|
||||
#endif /* RPL_CONF_MAX_DAG_PER_INSTANCE */
|
||||
|
||||
/*
|
||||
* RPL Default route lifetime
|
||||
* The RPL route lifetime is used for the downward routes and for the default
|
||||
* route. In a high density network with DIO suppression activated it may happen
|
||||
* that a node will never send a DIO once the DIO interval becomes high as it
|
||||
* has heard DIO from many neighbors already. As the default route to the
|
||||
* preferred parent has a lifetime reset by receiving DIO from the parent, it
|
||||
* means that the default route can be destroyed after a while. Setting the
|
||||
* default route with infinite lifetime secures the upstream route.
|
||||
*/
|
||||
#ifdef RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME
|
||||
#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME
|
||||
#else
|
||||
#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 0
|
||||
#endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -481,8 +481,7 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
|
|||
PRINT6ADDR(from);
|
||||
PRINTF("\n");
|
||||
instance->def_route = uip_ds6_defrt_add(from,
|
||||
RPL_LIFETIME(instance,
|
||||
instance->default_lifetime));
|
||||
RPL_DEFAULT_ROUTE_INFINITE_LIFETIME ? 0 : RPL_LIFETIME(instance, instance->default_lifetime));
|
||||
if(instance->def_route == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -814,6 +813,9 @@ rpl_select_parent(rpl_dag_t *dag)
|
|||
|
||||
if(best != NULL) {
|
||||
rpl_set_preferred_parent(dag, best);
|
||||
dag->rank = dag->instance->of->calculate_rank(dag->preferred_parent, 0);
|
||||
} else {
|
||||
dag->rank = INFINITE_RANK;
|
||||
}
|
||||
|
||||
return best;
|
||||
|
@ -1373,6 +1375,9 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
}
|
||||
}
|
||||
|
||||
/* Parent info has been updated, trigger rank recalculation */
|
||||
p->flags |= RPL_PARENT_FLAG_UPDATED;
|
||||
|
||||
PRINTF("RPL: preferred DAG ");
|
||||
PRINT6ADDR(&instance->current_dag->dag_id);
|
||||
PRINTF(", rank %u, min_rank %u, ",
|
||||
|
@ -1398,7 +1403,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
}
|
||||
/* We received a new DIO from our preferred parent.
|
||||
* Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */
|
||||
uip_ds6_defrt_add(from, RPL_LIFETIME(instance, instance->default_lifetime));
|
||||
uip_ds6_defrt_add(from, RPL_DEFAULT_ROUTE_INFINITE_LIFETIME ? 0 : RPL_LIFETIME(instance, instance->default_lifetime));
|
||||
}
|
||||
p->dtsn = dio->dtsn;
|
||||
}
|
||||
|
|
|
@ -277,9 +277,9 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
|
|||
rpl_instance_t *instance;
|
||||
rpl_instance_t *end;
|
||||
|
||||
PRINTF("RPL: Removing neighbor ");
|
||||
PRINTF("RPL: Neighbor state changed for ");
|
||||
PRINT6ADDR(&nbr->ipaddr);
|
||||
PRINTF("\n");
|
||||
PRINTF(", nscount=%u, state=%u\n", nbr->nscount, nbr->state);
|
||||
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
||||
if(instance->used == 1 ) {
|
||||
p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
|
||||
|
|
|
@ -61,7 +61,7 @@ typedef int32_t s32_t;
|
|||
#define HAVE_SNPRINTF
|
||||
#define snprintf(buf, len, ...) sprintf(buf, __VA_ARGS__)
|
||||
|
||||
#define CLOCK_CONF_SECOND 2
|
||||
#define CLOCK_CONF_SECOND 4
|
||||
typedef unsigned short clock_time_t;
|
||||
|
||||
typedef unsigned short uip_stats_t;
|
||||
|
@ -72,7 +72,6 @@ typedef unsigned short uip_stats_t;
|
|||
#define UIP_CONF_LLH_LEN 14
|
||||
#define RESOLV_CONF_SUPPORTS_MDNS 0
|
||||
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
||||
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 1
|
||||
|
||||
#define LOADER_CONF_ARCH "lib/unload.h"
|
||||
|
||||
|
@ -85,7 +84,7 @@ typedef unsigned short uip_stats_t;
|
|||
#if CONNECTIONS
|
||||
#define UIP_CONF_MAX_CONNECTIONS CONNECTIONS
|
||||
#else /* CONNECTIONS */
|
||||
#define UIP_CONF_MAX_CONNECTIONS 10
|
||||
#define UIP_CONF_MAX_CONNECTIONS 2
|
||||
#endif /* CONNECTIONS */
|
||||
|
||||
#if WITH_LOGGING
|
||||
|
|
|
@ -6,7 +6,7 @@ $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR)
|
|||
CUSTOM_RULE_C_TO_CO = 1
|
||||
%.co: %.c
|
||||
$(TRACE_CC)
|
||||
$(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE --create-dep $(@:.o=.d) $<
|
||||
$(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE $<
|
||||
|
||||
CUSTOM_RULE_LINK = 1
|
||||
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a
|
||||
|
|
|
@ -37,7 +37,7 @@ high-level configuration macros may be set:
|
|||
- Purpose: Set the Maximum Transfer Unit size.
|
||||
|
||||
- CONNECTIONS
|
||||
- Default: 10
|
||||
- Default: 2
|
||||
- Purpose: Set the maximum number of concurrent TCP connections.
|
||||
|
||||
- ETHERNET
|
||||
|
|
|
@ -212,7 +212,7 @@ PROCESS_THREAD(ipconfig_process, ev, data)
|
|||
if(ev == PROCESS_EVENT_MSG) {
|
||||
makestrings();
|
||||
ctk_window_redraw(&window);
|
||||
} else if(ev == tcpip_event) {
|
||||
} else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) {
|
||||
dhcpc_appcall(ev, data);
|
||||
} else if(ev == ctk_signal_button_activate) {
|
||||
if(data == (process_data_t)&requestbutton) {
|
||||
|
|
|
@ -92,12 +92,13 @@ fixups = * - fixup
|
|||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
rxtxreg := $FF00 ; High byte patched at runtime
|
||||
txcmd := $FF04 ; High byte patched at runtime
|
||||
txlen := $FF06 ; High byte patched at runtime
|
||||
isq := $FF08 ; High byte patched at runtime
|
||||
packetpp := $FF0A ; High byte patched at runtime
|
||||
ppdata := $FF0C ; High byte patched at runtime
|
||||
; 3 most significant nibbles are fixed up at runtime
|
||||
rxtxreg := $FFF0
|
||||
txcmd := $FFF4
|
||||
txlen := $FFF6
|
||||
isq := $FFF8
|
||||
packetpp := $FFFA
|
||||
ppdata := $FFFC
|
||||
|
||||
.data
|
||||
|
||||
|
@ -117,8 +118,9 @@ init:
|
|||
ldy #$00
|
||||
|
||||
; Fixup address at location
|
||||
: lda reg
|
||||
eor (ptr),y ; Use XOR to support C64 RR-Net
|
||||
: lda (ptr),y
|
||||
and #$0F
|
||||
eor reg ; Use XOR to support C64 RR-Net
|
||||
sta (ptr),y
|
||||
iny
|
||||
lda reg+1
|
||||
|
|
|
@ -95,40 +95,41 @@ fixups = * - fixup
|
|||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
ethbsr := $FF0E ; Bank select register R/W (2B)
|
||||
; 3 most significant nibbles are fixed up at runtime
|
||||
ethbsr := $FFFE ; Bank select register R/W (2B)
|
||||
|
||||
; Register bank 0
|
||||
ethtcr := $FF00 ; Transmition control register R/W (2B)
|
||||
ethephsr := $FF02 ; EPH status register R/O (2B)
|
||||
ethrcr := $FF04 ; Receive control register R/W (2B)
|
||||
ethecr := $FF06 ; Counter register R/O (2B)
|
||||
ethmir := $FF08 ; Memory information register R/O (2B)
|
||||
ethmcr := $FF0A ; Memory Config. reg. +0 R/W +1 R/O (2B)
|
||||
ethtcr := $FFF0 ; Transmition control register R/W (2B)
|
||||
ethephsr := $FFF2 ; EPH status register R/O (2B)
|
||||
ethrcr := $FFF4 ; Receive control register R/W (2B)
|
||||
ethecr := $FFF6 ; Counter register R/O (2B)
|
||||
ethmir := $FFF8 ; Memory information register R/O (2B)
|
||||
ethmcr := $FFFA ; Memory Config. reg. +0 R/W +1 R/O (2B)
|
||||
|
||||
; Register bank 1
|
||||
ethcr := $FF00 ; Configuration register R/W (2B)
|
||||
ethbar := $FF02 ; Base address register R/W (2B)
|
||||
ethiar := $FF04 ; Individual address register R/W (6B)
|
||||
ethgpr := $FF0A ; General address register R/W (2B)
|
||||
ethctr := $FF0C ; Control register R/W (2B)
|
||||
ethcr := $FFF0 ; Configuration register R/W (2B)
|
||||
ethbar := $FFF2 ; Base address register R/W (2B)
|
||||
ethiar := $FFF4 ; Individual address register R/W (6B)
|
||||
ethgpr := $FFFA ; General address register R/W (2B)
|
||||
ethctr := $FFFC ; Control register R/W (2B)
|
||||
|
||||
; Register bank 2
|
||||
ethmmucr := $FF00 ; MMU command register W/O (1B)
|
||||
ethautotx := $FF01 ; AUTO TX start register R/W (1B)
|
||||
ethpnr := $FF02 ; Packet number register R/W (1B)
|
||||
etharr := $FF03 ; Allocation result register R/O (1B)
|
||||
ethfifo := $FF04 ; FIFO ports register R/O (2B)
|
||||
ethptr := $FF06 ; Pointer register R/W (2B)
|
||||
ethdata := $FF08 ; Data register R/W (4B)
|
||||
ethist := $FF0C ; Interrupt status register R/O (1B)
|
||||
ethack := $FF0C ; Interrupt acknowledge register W/O (1B)
|
||||
ethmsk := $FF0D ; Interrupt mask register R/W (1B)
|
||||
ethmmucr := $FFF0 ; MMU command register W/O (1B)
|
||||
ethautotx := $FFF1 ; AUTO TX start register R/W (1B)
|
||||
ethpnr := $FFF2 ; Packet number register R/W (1B)
|
||||
etharr := $FFF3 ; Allocation result register R/O (1B)
|
||||
ethfifo := $FFF4 ; FIFO ports register R/O (2B)
|
||||
ethptr := $FFF6 ; Pointer register R/W (2B)
|
||||
ethdata := $FFF8 ; Data register R/W (4B)
|
||||
ethist := $FFFC ; Interrupt status register R/O (1B)
|
||||
ethack := $FFFC ; Interrupt acknowledge register W/O (1B)
|
||||
ethmsk := $FFFD ; Interrupt mask register R/W (1B)
|
||||
|
||||
; Register bank 3
|
||||
ethmt := $FF00 ; Multicast table R/W (8B)
|
||||
ethmgmt := $FF08 ; Management interface R/W (2B)
|
||||
ethrev := $FF0A ; Revision register R/W (2B)
|
||||
ethercv := $FF0C ; Early RCV register R/W (2B)
|
||||
ethmt := $FFF0 ; Multicast table R/W (8B)
|
||||
ethmgmt := $FFF8 ; Management interface R/W (2B)
|
||||
ethrev := $FFFA ; Revision register R/W (2B)
|
||||
ethercv := $FFFC ; Early RCV register R/W (2B)
|
||||
|
||||
.data
|
||||
|
||||
|
@ -148,8 +149,9 @@ init:
|
|||
ldy #$00
|
||||
|
||||
; Fixup address at location
|
||||
: lda reg
|
||||
ora (ptr),y
|
||||
: lda (ptr),y
|
||||
and #$0F
|
||||
ora reg
|
||||
sta (ptr),y
|
||||
iny
|
||||
lda reg+1
|
||||
|
|
|
@ -103,9 +103,10 @@ fixups = * - fixup
|
|||
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
mode := $FF00 ; High byte patched at runtime
|
||||
addr := $FF01 ; High byte patched at runtime
|
||||
data := $FF03 ; High byte patched at runtime
|
||||
; 14 most significant bits are fixed up at runtime
|
||||
mode := $FFFC|0
|
||||
addr := $FFFC|1
|
||||
data := $FFFC|3
|
||||
|
||||
.data
|
||||
|
||||
|
@ -125,8 +126,9 @@ init:
|
|||
ldy #$00
|
||||
|
||||
; Fixup address at location
|
||||
: lda reg
|
||||
ora (ptr),y
|
||||
: lda (ptr),y
|
||||
and #$03
|
||||
ora reg
|
||||
sta (ptr),y
|
||||
iny
|
||||
lda reg+1
|
||||
|
|
|
@ -45,11 +45,8 @@ clock_time(void)
|
|||
* of overhead for cc65 targets.
|
||||
* On the other hand we want to avoid wrapping around frequently so the idea
|
||||
* is to reduce the clock resolution to the bare minimum. This is defined by
|
||||
* the TCP/IP stack using a 1/2 second periodic timer. So CLOCK_CONF_SECOND
|
||||
* needs to be defined at least as 2.
|
||||
* The value 2 works out especially nicely as it allows us to implement the
|
||||
* clock frequency devider below purely in (32 bit) integer arithmetic based
|
||||
* on the educated guess of CLK_TCK being an even value. */
|
||||
* the DNS resolver using a 1/4 second timer. So CLOCK_CONF_SECOND needs to
|
||||
* be defined at least as 4. */
|
||||
return clock() / (CLK_TCK / CLOCK_CONF_SECOND);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -34,17 +34,17 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Cortex_M0
|
||||
* @defgroup Cortex_M0 Cortex-M0
|
||||
* @ingroup cmsis
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Cortex_M3
|
||||
* @defgroup Cortex_M3 Cortex-M3
|
||||
* @ingroup cmsis
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Cortex_M4
|
||||
* @defgroup Cortex_M4 Cortex-M4
|
||||
* @ingroup cmsis
|
||||
*/
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@
|
|||
* \addtogroup avr
|
||||
* @{ */
|
||||
/*!
|
||||
* \defgroup xgSmscRegs
|
||||
* \defgroup xgSmscRegs SMSC Registers
|
||||
*
|
||||
* @{ */
|
||||
|
||||
|
@ -1203,6 +1203,7 @@ PROCESS_THREAD(lanc111_process, ev, data)
|
|||
PROCESS_END();
|
||||
}
|
||||
#endif /* 0 */
|
||||
#if 0
|
||||
/*!
|
||||
* \brief Send Ethernet packet.
|
||||
*
|
||||
|
@ -1213,7 +1214,6 @@ PROCESS_THREAD(lanc111_process, ev, data)
|
|||
*
|
||||
* \return 0 on success, -1 in case of any errors.
|
||||
*/
|
||||
#if 0
|
||||
int LancOutput(NUTDEVICE * dev, NETBUF * nb)
|
||||
{
|
||||
static u_long mx_wait = 5000;
|
||||
|
|
|
@ -544,6 +544,7 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length)
|
|||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#if 0 //Uses 80 bytes (on Raven) omit unless needed
|
||||
/** \brief Read SRAM
|
||||
*
|
||||
* This function reads from the SRAM of the radio transceiver.
|
||||
|
@ -552,7 +553,6 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length)
|
|||
* \param length Length of the read burst
|
||||
* \param data Pointer to buffer where data is stored.
|
||||
*/
|
||||
#if 0 //Uses 80 bytes (on Raven) omit unless needed
|
||||
void
|
||||
hal_sram_read(uint8_t address, uint8_t length, uint8_t *data)
|
||||
{
|
||||
|
@ -576,6 +576,7 @@ hal_sram_read(uint8_t address, uint8_t length, uint8_t *data)
|
|||
}
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#if 0 //omit unless needed
|
||||
/** \brief Write SRAM
|
||||
*
|
||||
* This function writes into the SRAM of the radio transceiver. It can reduce
|
||||
|
@ -585,7 +586,6 @@ hal_sram_read(uint8_t address, uint8_t length, uint8_t *data)
|
|||
* \param length Length of the write burst
|
||||
* \param data Pointer to an array of bytes that should be written
|
||||
*/
|
||||
#if 0 //omit unless needed
|
||||
void
|
||||
hal_sram_write(uint8_t address, uint8_t length, uint8_t *data)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm
|
|||
### CPU-dependent source files
|
||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c
|
||||
CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
|
||||
CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ccm.c sha256.c
|
||||
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
|
||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
||||
|
|
|
@ -85,12 +85,13 @@ SECTIONS
|
|||
*(.udma_channel_control_table)
|
||||
} > SRAM
|
||||
|
||||
.data :
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data = .;
|
||||
*(.data*)
|
||||
_edata = .;
|
||||
} > SRAM AT > FLASH
|
||||
_ldata = LOADADDR(.data);
|
||||
|
||||
.ARM.exidx :
|
||||
{
|
||||
|
@ -105,6 +106,11 @@ SECTIONS
|
|||
_ebss = .;
|
||||
} > SRAM
|
||||
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
*(.stack)
|
||||
} > SRAM
|
||||
|
||||
#if (LPM_CONF_MAX_PM==2) && (LPM_CONF_ENABLE != 0)
|
||||
.nrdata (NOLOAD) :
|
||||
{
|
||||
|
|
152
cpu/cc2538/dev/aes.c
Normal file
152
cpu/cc2538/dev/aes.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-aes
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 AES driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/aes.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
aes_load_keys(const void *keys, uint8_t key_size, uint8_t count,
|
||||
uint8_t start_area)
|
||||
{
|
||||
uint32_t aes_key_store_size;
|
||||
uint32_t areas;
|
||||
uint64_t aligned_keys[16];
|
||||
int i;
|
||||
|
||||
if(REG(AES_CTRL_ALG_SEL) != 0x00000000) {
|
||||
return CRYPTO_RESOURCE_IN_USE;
|
||||
}
|
||||
|
||||
/* 192-bit keys must be padded to 256 bits */
|
||||
if(key_size == AES_KEY_STORE_SIZE_KEY_SIZE_192) {
|
||||
for(i = 0; i < count; i++) {
|
||||
rom_util_memcpy(&aligned_keys[i << 2], &((uint64_t *)keys)[i * 3], 24);
|
||||
aligned_keys[(i << 2) + 3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change count to the number of 128-bit key areas */
|
||||
if(key_size != AES_KEY_STORE_SIZE_KEY_SIZE_128) {
|
||||
count <<= 1;
|
||||
}
|
||||
|
||||
/* The keys base address needs to be 4-byte aligned */
|
||||
if(key_size != AES_KEY_STORE_SIZE_KEY_SIZE_192) {
|
||||
rom_util_memcpy(aligned_keys, keys, count << 4);
|
||||
}
|
||||
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
/* Configure master control module */
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_KEYSTORE;
|
||||
|
||||
/* Clear any outstanding events */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Configure key store module (areas, size)
|
||||
* Note that writing AES_KEY_STORE_SIZE deletes all stored keys */
|
||||
aes_key_store_size = REG(AES_KEY_STORE_SIZE);
|
||||
if((aes_key_store_size & AES_KEY_STORE_SIZE_KEY_SIZE_M) != key_size) {
|
||||
REG(AES_KEY_STORE_SIZE) = (aes_key_store_size &
|
||||
~AES_KEY_STORE_SIZE_KEY_SIZE_M) | key_size;
|
||||
}
|
||||
|
||||
/* Free possibly already occupied key areas */
|
||||
areas = ((0x00000001 << count) - 1) << start_area;
|
||||
REG(AES_KEY_STORE_WRITTEN_AREA) = areas;
|
||||
|
||||
/* Enable key areas to write */
|
||||
REG(AES_KEY_STORE_WRITE_AREA) = areas;
|
||||
|
||||
/* Configure DMAC
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
|
||||
/* Base address of the keys in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)aligned_keys;
|
||||
|
||||
/* Total keys length in bytes (e.g. 16 for 1 x 128-bit key) */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = (REG(AES_DMAC_CH0_DMALENGTH) &
|
||||
~AES_DMAC_CH_DMALENGTH_DMALEN_M) |
|
||||
(count << (4 + AES_DMAC_CH_DMALENGTH_DMALEN_S));
|
||||
|
||||
/* Wait for operation to complete */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV));
|
||||
|
||||
/* Check for absence of errors in DMA and key store */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) {
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_WR_ERR;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
/* Acknowledge the interrupt */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
|
||||
/* Check status, if error return error code */
|
||||
if((REG(AES_KEY_STORE_WRITTEN_AREA) & areas) != areas) {
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/** @} */
|
495
cpu/cc2538/dev/aes.h
Normal file
495
cpu/cc2538/dev/aes.h
Normal file
|
@ -0,0 +1,495 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-crypto
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-aes cc2538 AES
|
||||
*
|
||||
* Driver for the cc2538 AES modes of the security core
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 AES driver
|
||||
*/
|
||||
#ifndef AES_H_
|
||||
#define AES_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/crypto.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES register offsets
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_CH0_CTRL 0x4008B000 /**< Channel 0 control */
|
||||
#define AES_DMAC_CH0_EXTADDR 0x4008B004 /**< Channel 0 external address */
|
||||
#define AES_DMAC_CH0_DMALENGTH 0x4008B00C /**< Channel 0 DMA length */
|
||||
#define AES_DMAC_STATUS 0x4008B018 /**< DMAC status */
|
||||
#define AES_DMAC_SWRES 0x4008B01C /**< DMAC software reset */
|
||||
#define AES_DMAC_CH1_CTRL 0x4008B020 /**< Channel 1 control */
|
||||
#define AES_DMAC_CH1_EXTADDR 0x4008B024 /**< Channel 1 external address */
|
||||
#define AES_DMAC_CH1_DMALENGTH 0x4008B02C /**< Channel 1 DMA length */
|
||||
#define AES_DMAC_MST_RUNPARAMS 0x4008B078 /**< DMAC master run-time parameters */
|
||||
#define AES_DMAC_PERSR 0x4008B07C /**< DMAC port error raw status */
|
||||
#define AES_DMAC_OPTIONS 0x4008B0F8 /**< DMAC options */
|
||||
#define AES_DMAC_VERSION 0x4008B0FC /**< DMAC version */
|
||||
#define AES_KEY_STORE_WRITE_AREA \
|
||||
0x4008B400 /**< Key store write area */
|
||||
#define AES_KEY_STORE_WRITTEN_AREA \
|
||||
0x4008B404 /**< Key store written area */
|
||||
#define AES_KEY_STORE_SIZE 0x4008B408 /**< Key store size */
|
||||
#define AES_KEY_STORE_READ_AREA 0x4008B40C /**< Key store read area */
|
||||
#define AES_AES_KEY2_0 0x4008B500 /**< AES_KEY2_0 / AES_GHASH_H_IN_0 */
|
||||
#define AES_AES_KEY2_1 0x4008B504 /**< AES_KEY2_1 / AES_GHASH_H_IN_1 */
|
||||
#define AES_AES_KEY2_2 0x4008B508 /**< AES_KEY2_2 / AES_GHASH_H_IN_2 */
|
||||
#define AES_AES_KEY2_3 0x4008B50C /**< AES_KEY2_3 / AES_GHASH_H_IN_3 */
|
||||
#define AES_AES_KEY3_0 0x4008B510 /**< AES_KEY3_0 / AES_KEY2_4 */
|
||||
#define AES_AES_KEY3_1 0x4008B514 /**< AES_KEY3_1 / AES_KEY2_5 */
|
||||
#define AES_AES_KEY3_2 0x4008B518 /**< AES_KEY3_2 / AES_KEY2_6 */
|
||||
#define AES_AES_KEY3_3 0x4008B51C /**< AES_KEY3_3 / AES_KEY2_7 */
|
||||
#define AES_AES_IV_0 0x4008B540 /**< AES initialization vector */
|
||||
#define AES_AES_IV_1 0x4008B544 /**< AES initialization vector */
|
||||
#define AES_AES_IV_2 0x4008B548 /**< AES initialization vector */
|
||||
#define AES_AES_IV_3 0x4008B54C /**< AES initialization vector */
|
||||
#define AES_AES_CTRL 0x4008B550 /**< AES input/output buffer control and mode */
|
||||
#define AES_AES_C_LENGTH_0 0x4008B554 /**< AES crypto length (LSW) */
|
||||
#define AES_AES_C_LENGTH_1 0x4008B558 /**< AES crypto length (MSW) */
|
||||
#define AES_AES_AUTH_LENGTH 0x4008B55C /**< Authentication length */
|
||||
#define AES_AES_DATA_IN_OUT_0 0x4008B560 /**< Data input/output */
|
||||
#define AES_AES_DATA_IN_OUT_1 0x4008B564 /**< Data Input/Output */
|
||||
#define AES_AES_DATA_IN_OUT_2 0x4008B568 /**< Data Input/Output */
|
||||
#define AES_AES_DATA_IN_OUT_3 0x4008B56C /**< Data Input/Output */
|
||||
#define AES_AES_TAG_OUT_0 0x4008B570 /**< TAG */
|
||||
#define AES_AES_TAG_OUT_1 0x4008B574 /**< TAG */
|
||||
#define AES_AES_TAG_OUT_2 0x4008B578 /**< TAG */
|
||||
#define AES_AES_TAG_OUT_3 0x4008B57C /**< TAG */
|
||||
#define AES_HASH_DATA_IN_0 0x4008B600 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_1 0x4008B604 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_2 0x4008B608 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_3 0x4008B60C /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_4 0x4008B610 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_5 0x4008B614 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_6 0x4008B618 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_7 0x4008B61C /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_8 0x4008B620 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_9 0x4008B624 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_10 0x4008B628 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_11 0x4008B62C /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_12 0x4008B630 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_13 0x4008B634 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_14 0x4008B638 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_15 0x4008B63C /**< HASH data input */
|
||||
#define AES_HASH_IO_BUF_CTRL 0x4008B640 /**< Input/output buffer control and status */
|
||||
#define AES_HASH_MODE_IN 0x4008B644 /**< Hash mode */
|
||||
#define AES_HASH_LENGTH_IN_L 0x4008B648 /**< Hash length */
|
||||
#define AES_HASH_LENGTH_IN_H 0x4008B64C /**< Hash length */
|
||||
#define AES_HASH_DIGEST_A 0x4008B650 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_B 0x4008B654 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_C 0x4008B658 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_D 0x4008B65C /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_E 0x4008B660 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_F 0x4008B664 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_G 0x4008B668 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_H 0x4008B66C /**< Hash digest */
|
||||
#define AES_CTRL_ALG_SEL 0x4008B700 /**< Algorithm select */
|
||||
#define AES_CTRL_PROT_EN 0x4008B704 /**< Master PROT privileged access enable */
|
||||
#define AES_CTRL_SW_RESET 0x4008B740 /**< Software reset */
|
||||
#define AES_CTRL_INT_CFG 0x4008B780 /**< Interrupt configuration */
|
||||
#define AES_CTRL_INT_EN 0x4008B784 /**< Interrupt enable */
|
||||
#define AES_CTRL_INT_CLR 0x4008B788 /**< Interrupt clear */
|
||||
#define AES_CTRL_INT_SET 0x4008B78C /**< Interrupt set */
|
||||
#define AES_CTRL_INT_STAT 0x4008B790 /**< Interrupt status */
|
||||
#define AES_CTRL_OPTIONS 0x4008B7F8 /**< Options */
|
||||
#define AES_CTRL_VERSION 0x4008B7FC /**< Version */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_CHx_CTRL registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_CH_CTRL_PRIO 0x00000002 /**< Channel priority 0: Low 1: High */
|
||||
#define AES_DMAC_CH_CTRL_EN 0x00000001 /**< Channel enable */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_CHx_DMALENGTH registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_CH_DMALENGTH_DMALEN_M \
|
||||
0x0000FFFF /**< Channel DMA length in bytes mask */
|
||||
#define AES_DMAC_CH_DMALENGTH_DMALEN_S 0 /**< Channel DMA length in bytes shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_STATUS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_STATUS_PORT_ERR \
|
||||
0x00020000 /**< AHB port transfer errors */
|
||||
#define AES_DMAC_STATUS_CH1_ACT 0x00000002 /**< Channel 1 active (DMA transfer on-going) */
|
||||
#define AES_DMAC_STATUS_CH0_ACT 0x00000001 /**< Channel 0 active (DMA transfer on-going) */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_SWRES register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_SWRES_SWRES 0x00000001 /**< Software reset enable */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_MST_RUNPARAMS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_4 \
|
||||
(2 << 12) /**< Maximum burst size: 4 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_8 \
|
||||
(3 << 12) /**< Maximum burst size: 8 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_16 \
|
||||
(4 << 12) /**< Maximum burst size: 16 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_32 \
|
||||
(5 << 12) /**< Maximum burst size: 32 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_64 \
|
||||
(6 << 12) /**< Maximum burst size: 64 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_M \
|
||||
0x0000F000 /**< Maximum burst size mask */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_S \
|
||||
12 /**< Maximum burst size shift */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_IDLE_EN \
|
||||
0x00000800 /**< Idle insertion between bursts */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_INCR_EN \
|
||||
0x00000400 /**< Fixed-length burst or single transfers */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_LOCK_EN \
|
||||
0x00000200 /**< Locked transfers */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BIGEND \
|
||||
0x00000100 /**< Big endian AHB master */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_PERSR register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_PERSR_PORT1_AHB_ERROR \
|
||||
0x00001000 /**< AHB bus error */
|
||||
#define AES_DMAC_PERSR_PORT1_CHANNEL \
|
||||
0x00000200 /**< Last serviced channel (0 or 1) */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_OPTIONS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_M \
|
||||
0x00000F00 /**< Number of channels implemented mask */
|
||||
#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_S \
|
||||
8 /**< Number of channels implemented shift */
|
||||
#define AES_DMAC_OPTIONS_NR_OF_PORTS_M \
|
||||
0x00000007 /**< Number of ports implemented mask */
|
||||
#define AES_DMAC_OPTIONS_NR_OF_PORTS_S 0 /**< Number of ports implemented shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_VERSION register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_VERSION_HW_MAJOR_VERSION_M \
|
||||
0x0F000000 /**< Major version number mask */
|
||||
#define AES_DMAC_VERSION_HW_MAJOR_VERSION_S \
|
||||
24 /**< Major version number shift */
|
||||
#define AES_DMAC_VERSION_HW_MINOR_VERSION_M \
|
||||
0x00F00000 /**< Minor version number mask */
|
||||
#define AES_DMAC_VERSION_HW_MINOR_VERSION_S \
|
||||
20 /**< Minor version number shift */
|
||||
#define AES_DMAC_VERSION_HW_PATCH_LEVEL_M \
|
||||
0x000F0000 /**< Patch level mask */
|
||||
#define AES_DMAC_VERSION_HW_PATCH_LEVEL_S \
|
||||
16 /**< Patch level shift */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_M \
|
||||
0x0000FF00 /**< EIP_NUMBER 1's complement mask */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_S \
|
||||
8 /**< EIP_NUMBER 1's complement shift */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_M \
|
||||
0x000000FF /**< DMAC EIP-number mask */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_S 0 /**< DMAC EIP-number shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_KEY_STORE_SIZE register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_128 1 /**< Key size: 128 bits */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_192 2 /**< Key size: 192 bits */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_256 3 /**< Key size: 256 bits */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_M \
|
||||
0x00000003 /**< Key size mask */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_S 0 /**< Key size shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_KEY_STORE_READ_AREA register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_KEY_STORE_READ_AREA_BUSY \
|
||||
0x80000000 /**< Key store operation busy */
|
||||
#define AES_KEY_STORE_READ_AREA_RAM_AREA_M \
|
||||
0x0000000F /**< Key store RAM area select mask */
|
||||
#define AES_KEY_STORE_READ_AREA_RAM_AREA_S \
|
||||
0 /**< Key store RAM area select shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_AES_CTRL register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_AES_CTRL_CONTEXT_READY \
|
||||
0x80000000 /**< Context data registers can be overwritten */
|
||||
#define AES_AES_CTRL_SAVED_CONTEXT_READY \
|
||||
0x40000000 /**< AES auth. TAG and/or IV block(s) available */
|
||||
#define AES_AES_CTRL_SAVE_CONTEXT \
|
||||
0x20000000 /**< Auth. TAG or result IV needs to be stored */
|
||||
#define AES_AES_CTRL_CCM_M_M 0x01C00000 /**< CCM auth. field length mask */
|
||||
#define AES_AES_CTRL_CCM_M_S 22 /**< CCM auth. field length shift */
|
||||
#define AES_AES_CTRL_CCM_L_M 0x00380000 /**< CCM length field width mask */
|
||||
#define AES_AES_CTRL_CCM_L_S 19 /**< CCM length field width shift */
|
||||
#define AES_AES_CTRL_CCM 0x00040000 /**< AES-CCM mode */
|
||||
#define AES_AES_CTRL_GCM 0x00030000 /**< AES-GCM mode */
|
||||
#define AES_AES_CTRL_CBC_MAC 0x00008000 /**< AES-CBC MAC mode */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_32 (0 << 7) /**< CTR counter width: 32 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_64 (1 << 7) /**< CTR counter width: 64 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_96 (2 << 7) /**< CTR counter width: 96 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_128 \
|
||||
(3 << 7) /**< CTR counter width: 128 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_M \
|
||||
0x00000180 /**< CTR counter width mask */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_S 7 /**< CTR counter width shift */
|
||||
#define AES_AES_CTRL_CTR 0x00000040 /**< AES-CTR mode */
|
||||
#define AES_AES_CTRL_CBC 0x00000020 /**< AES-CBC mode */
|
||||
#define AES_AES_CTRL_KEY_SIZE_128 (1 << 3) /**< Key size: 128 bits */
|
||||
#define AES_AES_CTRL_KEY_SIZE_192 (2 << 3) /**< Key size: 192 bits */
|
||||
#define AES_AES_CTRL_KEY_SIZE_256 (3 << 3) /**< Key size: 256 bits */
|
||||
#define AES_AES_CTRL_KEY_SIZE_M 0x00000018 /**< Key size mask */
|
||||
#define AES_AES_CTRL_KEY_SIZE_S 3 /**< Key size shift */
|
||||
#define AES_AES_CTRL_DIRECTION_ENCRYPT \
|
||||
0x00000004 /**< Encrypt */
|
||||
#define AES_AES_CTRL_INPUT_READY \
|
||||
0x00000002 /**< AES input buffer empty */
|
||||
#define AES_AES_CTRL_OUTPUT_READY \
|
||||
0x00000001 /**< AES output block available */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_AES_C_LENGTH_1 register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_AES_C_LENGTH_1_C_LENGTH_M \
|
||||
0x1FFFFFFF /**< Crypto length bits [60:32] mask */
|
||||
#define AES_AES_C_LENGTH_1_C_LENGTH_S 0 /**< Crypto length bits [60:32] shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_HASH_IO_BUF_CTRL register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE \
|
||||
0x00000080 /**< Hash engine message padding required */
|
||||
#define AES_HASH_IO_BUF_CTRL_GET_DIGEST \
|
||||
0x00000040 /**< Hash engine digest requested */
|
||||
#define AES_HASH_IO_BUF_CTRL_PAD_MESSAGE \
|
||||
0x00000020 /**< Last message data in HASH_DATA_IN, apply hash padding */
|
||||
#define AES_HASH_IO_BUF_CTRL_RFD_IN \
|
||||
0x00000004 /**< Hash engine input buffer can accept new data */
|
||||
#define AES_HASH_IO_BUF_CTRL_DATA_IN_AV \
|
||||
0x00000002 /**< Start processing HASH_DATA_IN data */
|
||||
#define AES_HASH_IO_BUF_CTRL_OUTPUT_FULL \
|
||||
0x00000001 /**< Output buffer registers available */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_HASH_MODE_IN register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_HASH_MODE_IN_SHA256_MODE \
|
||||
0x00000008 /**< Hash mode */
|
||||
#define AES_HASH_MODE_IN_NEW_HASH \
|
||||
0x00000001 /**< New hash session */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_ALG_SEL register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_ALG_SEL_TAG 0x80000000 /**< DMA operation includes TAG */
|
||||
#define AES_CTRL_ALG_SEL_HASH 0x00000004 /**< Select hash engine as DMA destination */
|
||||
#define AES_CTRL_ALG_SEL_AES 0x00000002 /**< Select AES engine as DMA source/destination */
|
||||
#define AES_CTRL_ALG_SEL_KEYSTORE \
|
||||
0x00000001 /**< Select Key Store as DMA destination */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_PROT_EN register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_PROT_EN_PROT_EN \
|
||||
0x00000001 /**< m_h_prot[1] asserted for DMA reads towards key store */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_SW_RESET register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_SW_RESET_SW_RESET \
|
||||
0x00000001 /**< Reset master control and key store */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_CFG register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_CFG_LEVEL 0x00000001 /**< Level interrupt type */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_EN register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_EN_DMA_IN_DONE \
|
||||
0x00000002 /**< DMA input done interrupt enabled */
|
||||
#define AES_CTRL_INT_EN_RESULT_AV \
|
||||
0x00000001 /**< Result available interrupt enabled */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_CLR register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_CLR_DMA_BUS_ERR \
|
||||
0x80000000 /**< Clear DMA bus error status */
|
||||
#define AES_CTRL_INT_CLR_KEY_ST_WR_ERR \
|
||||
0x40000000 /**< Clear key store write error status */
|
||||
#define AES_CTRL_INT_CLR_KEY_ST_RD_ERR \
|
||||
0x20000000 /**< Clear key store read error status */
|
||||
#define AES_CTRL_INT_CLR_DMA_IN_DONE \
|
||||
0x00000002 /**< Clear DMA in done interrupt */
|
||||
#define AES_CTRL_INT_CLR_RESULT_AV \
|
||||
0x00000001 /**< Clear result available interrupt */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_SET register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_SET_DMA_IN_DONE \
|
||||
0x00000002 /**< Set DMA data in done interrupt */
|
||||
#define AES_CTRL_INT_SET_RESULT_AV \
|
||||
0x00000001 /**< Set result available interrupt */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_STAT register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_STAT_DMA_BUS_ERR \
|
||||
0x80000000 /**< DMA bus error detected */
|
||||
#define AES_CTRL_INT_STAT_KEY_ST_WR_ERR \
|
||||
0x40000000 /**< Write error detected */
|
||||
#define AES_CTRL_INT_STAT_KEY_ST_RD_ERR \
|
||||
0x20000000 /**< Read error detected */
|
||||
#define AES_CTRL_INT_STAT_DMA_IN_DONE \
|
||||
0x00000002 /**< DMA data in done interrupt status */
|
||||
#define AES_CTRL_INT_STAT_RESULT_AV \
|
||||
0x00000001 /**< Result available interrupt status */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_OPTIONS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_OPTIONS_TYPE_M 0xFF000000 /**< Device type mask */
|
||||
#define AES_CTRL_OPTIONS_TYPE_S 24 /**< Device type shift */
|
||||
#define AES_CTRL_OPTIONS_AHBINTERFACE \
|
||||
0x00010000 /**< AHB interface available */
|
||||
#define AES_CTRL_OPTIONS_SHA_256 \
|
||||
0x00000100 /**< The HASH core supports SHA-256 */
|
||||
#define AES_CTRL_OPTIONS_AES_CCM \
|
||||
0x00000080 /**< AES-CCM available as single operation */
|
||||
#define AES_CTRL_OPTIONS_AES_GCM \
|
||||
0x00000040 /**< AES-GCM available as single operation */
|
||||
#define AES_CTRL_OPTIONS_AES_256 \
|
||||
0x00000020 /**< AES core supports 256-bit keys */
|
||||
#define AES_CTRL_OPTIONS_AES_128 \
|
||||
0x00000010 /**< AES core supports 128-bit keys */
|
||||
#define AES_CTRL_OPTIONS_HASH 0x00000004 /**< HASH Core available */
|
||||
#define AES_CTRL_OPTIONS_AES 0x00000002 /**< AES core available */
|
||||
#define AES_CTRL_OPTIONS_KEYSTORE \
|
||||
0x00000001 /**< KEY STORE available */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_VERSION register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_VERSION_MAJOR_VERSION_M \
|
||||
0x0F000000 /**< Major version number mask */
|
||||
#define AES_CTRL_VERSION_MAJOR_VERSION_S \
|
||||
24 /**< Major version number shift */
|
||||
#define AES_CTRL_VERSION_MINOR_VERSION_M \
|
||||
0x00F00000 /**< Minor version number mask */
|
||||
#define AES_CTRL_VERSION_MINOR_VERSION_S \
|
||||
20 /**< Minor version number shift */
|
||||
#define AES_CTRL_VERSION_PATCH_LEVEL_M \
|
||||
0x000F0000 /**< Patch level mask */
|
||||
#define AES_CTRL_VERSION_PATCH_LEVEL_S 16 /**< Patch level shift */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_M \
|
||||
0x0000FF00 /**< EIP_NUMBER 1's complement mask */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_S \
|
||||
8 /**< EIP_NUMBER 1's complement shift */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_M \
|
||||
0x000000FF /**< EIP-120t EIP-number mask */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_S 0 /**< EIP-120t EIP-number shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES drivers return codes
|
||||
* @{
|
||||
*/
|
||||
#define AES_KEYSTORE_READ_ERROR 5
|
||||
#define AES_KEYSTORE_WRITE_ERROR 6
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Writes keys into the Key RAM
|
||||
* \param keys Pointer to AES Keys
|
||||
* \param key_size Key size: \c AES_KEY_STORE_SIZE_KEY_SIZE_x
|
||||
* \param count Number of keys (1 to 8 - \p start_area for 128-bit keys, 1 to
|
||||
* (8 - \p start_area) / 2 for 192- and 256-bit keys)
|
||||
* \param start_area Start area in Key RAM where to store the key (0 to 7, must
|
||||
* be even for 192- and 256-bit keys)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES error code
|
||||
* \note Calling this function with a value of \p key_size different from the
|
||||
* one passed for the previous calls causes the deletion of all previously
|
||||
* stored keys.
|
||||
*/
|
||||
uint8_t aes_load_keys(const void *keys, uint8_t key_size, uint8_t count,
|
||||
uint8_t start_area);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* AES_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
413
cpu/cc2538/dev/ccm.c
Normal file
413
cpu/cc2538/dev/ccm.c
Normal file
|
@ -0,0 +1,413 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-ccm
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 AES-CCM driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/nvic.h"
|
||||
#include "dev/ccm.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce,
|
||||
const void *adata, uint16_t adata_len, void *pdata,
|
||||
uint16_t pdata_len, uint8_t mic_len,
|
||||
struct process *process)
|
||||
{
|
||||
uint32_t iv[4];
|
||||
|
||||
if(REG(AES_CTRL_ALG_SEL) != 0x00000000) {
|
||||
return CRYPTO_RESOURCE_IN_USE;
|
||||
}
|
||||
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES;
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
REG(AES_KEY_STORE_READ_AREA) = key_area;
|
||||
|
||||
/* Wait until key is loaded to the AES module */
|
||||
while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY);
|
||||
|
||||
/* Check for Key Store read error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
/* Clear the Keystore Read error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Prepare the encryption initialization vector
|
||||
* Flags: L' = L - 1 */
|
||||
((uint8_t *)iv)[0] = len_len - 1;
|
||||
/* Nonce */
|
||||
rom_util_memcpy(&((uint8_t *)iv)[1], nonce, 15 - len_len);
|
||||
/* Initialize counter to 0 */
|
||||
rom_util_memset(&((uint8_t *)iv)[16 - len_len], 0, len_len);
|
||||
|
||||
/* Write initialization vector */
|
||||
REG(AES_AES_IV_0) = iv[0];
|
||||
REG(AES_AES_IV_1) = iv[1];
|
||||
REG(AES_AES_IV_2) = iv[2];
|
||||
REG(AES_AES_IV_3) = iv[3];
|
||||
|
||||
/* Program AES-CCM encryption */
|
||||
REG(AES_AES_CTRL) = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */
|
||||
(((MAX(mic_len, 2) - 2) >> 1) << AES_AES_CTRL_CCM_M_S) | /* M */
|
||||
((len_len - 1) << AES_AES_CTRL_CCM_L_S) | /* L */
|
||||
AES_AES_CTRL_CCM | /* CCM */
|
||||
AES_AES_CTRL_CTR_WIDTH_128 | /* CTR width 128 */
|
||||
AES_AES_CTRL_CTR | /* CTR */
|
||||
AES_AES_CTRL_DIRECTION_ENCRYPT; /* Encryption */
|
||||
|
||||
/* Write the length of the crypto block (lo) */
|
||||
REG(AES_AES_C_LENGTH_0) = pdata_len;
|
||||
/* Write the length of the crypto block (hi) */
|
||||
REG(AES_AES_C_LENGTH_1) = 0;
|
||||
|
||||
/* Write the length of the AAD data block (may be non-block size-aligned) */
|
||||
REG(AES_AES_AUTH_LENGTH) = adata_len;
|
||||
|
||||
if(adata_len != 0) {
|
||||
/* Configure DMAC to fetch the AAD data
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the AAD input data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata;
|
||||
/* AAD data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = adata_len;
|
||||
|
||||
/* Wait for completion of the AAD data transfer, DMA_IN_DONE */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE));
|
||||
|
||||
/* Check for the absence of error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
if(process != NULL) {
|
||||
crypto_register_process_notification(process);
|
||||
nvic_interrupt_unpend(NVIC_INT_AES);
|
||||
nvic_interrupt_enable(NVIC_INT_AES);
|
||||
}
|
||||
|
||||
/* Enable result available bit in interrupt enable */
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
if(pdata_len != 0) {
|
||||
/* Configure DMAC
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the payload data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pdata;
|
||||
/* Payload data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = pdata_len;
|
||||
|
||||
/* Enable DMA channel 1 */
|
||||
REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the output data buffer */
|
||||
REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)pdata;
|
||||
/* Output data length in bytes */
|
||||
REG(AES_DMAC_CH1_DMALENGTH) = pdata_len;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_encrypt_check_status(void)
|
||||
{
|
||||
return !!(REG(AES_CTRL_INT_STAT) &
|
||||
(AES_CTRL_INT_STAT_DMA_BUS_ERR | AES_CTRL_INT_STAT_KEY_ST_WR_ERR |
|
||||
AES_CTRL_INT_STAT_KEY_ST_RD_ERR | AES_CTRL_INT_STAT_RESULT_AV));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len)
|
||||
{
|
||||
uint32_t aes_ctrl_int_stat;
|
||||
uint32_t tag[4];
|
||||
|
||||
aes_ctrl_int_stat = REG(AES_CTRL_INT_STAT);
|
||||
/* Clear the error bits */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR |
|
||||
AES_CTRL_INT_CLR_KEY_ST_WR_ERR |
|
||||
AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
|
||||
nvic_interrupt_disable(NVIC_INT_AES);
|
||||
crypto_register_process_notification(NULL);
|
||||
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
|
||||
if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) {
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Read tag
|
||||
* Wait for the context ready bit */
|
||||
while(!(REG(AES_AES_CTRL) & AES_AES_CTRL_SAVED_CONTEXT_READY));
|
||||
|
||||
/* Read the tag registers */
|
||||
tag[0] = REG(AES_AES_TAG_OUT_0);
|
||||
tag[1] = REG(AES_AES_TAG_OUT_1);
|
||||
tag[2] = REG(AES_AES_TAG_OUT_2);
|
||||
tag[3] = REG(AES_AES_TAG_OUT_3);
|
||||
|
||||
/* Clear the interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Copy tag to MIC */
|
||||
rom_util_memcpy(mic, tag, mic_len);
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce,
|
||||
const void *adata, uint16_t adata_len, void *cdata,
|
||||
uint16_t cdata_len, uint8_t mic_len,
|
||||
struct process *process)
|
||||
{
|
||||
uint16_t pdata_len = cdata_len - mic_len;
|
||||
uint32_t iv[4];
|
||||
|
||||
if(REG(AES_CTRL_ALG_SEL) != 0x00000000) {
|
||||
return CRYPTO_RESOURCE_IN_USE;
|
||||
}
|
||||
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES;
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
REG(AES_KEY_STORE_READ_AREA) = key_area;
|
||||
|
||||
/* Wait until key is loaded to the AES module */
|
||||
while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY);
|
||||
|
||||
/* Check for Key Store read error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
/* Clear the Keystore Read error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Prepare the decryption initialization vector
|
||||
* Flags: L' = L - 1 */
|
||||
((uint8_t *)iv)[0] = len_len - 1;
|
||||
/* Nonce */
|
||||
rom_util_memcpy(&((uint8_t *)iv)[1], nonce, 15 - len_len);
|
||||
/* Initialize counter to 0 */
|
||||
rom_util_memset(&((uint8_t *)iv)[16 - len_len], 0, len_len);
|
||||
|
||||
/* Write initialization vector */
|
||||
REG(AES_AES_IV_0) = iv[0];
|
||||
REG(AES_AES_IV_1) = iv[1];
|
||||
REG(AES_AES_IV_2) = iv[2];
|
||||
REG(AES_AES_IV_3) = iv[3];
|
||||
|
||||
/* Program AES-CCM decryption */
|
||||
REG(AES_AES_CTRL) = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */
|
||||
(((MAX(mic_len, 2) - 2) >> 1) << AES_AES_CTRL_CCM_M_S) | /* M */
|
||||
((len_len - 1) << AES_AES_CTRL_CCM_L_S) | /* L */
|
||||
AES_AES_CTRL_CCM | /* CCM */
|
||||
AES_AES_CTRL_CTR_WIDTH_128 | /* CTR width 128 */
|
||||
AES_AES_CTRL_CTR; /* CTR */
|
||||
|
||||
/* Write the length of the crypto block (lo) */
|
||||
REG(AES_AES_C_LENGTH_0) = pdata_len;
|
||||
/* Write the length of the crypto block (hi) */
|
||||
REG(AES_AES_C_LENGTH_1) = 0;
|
||||
|
||||
/* Write the length of the AAD data block (may be non-block size-aligned) */
|
||||
REG(AES_AES_AUTH_LENGTH) = adata_len;
|
||||
|
||||
if(adata_len != 0) {
|
||||
/* Configure DMAC to fetch the AAD data
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the AAD input data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata;
|
||||
/* AAD data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = adata_len;
|
||||
|
||||
/* Wait for completion of the AAD data transfer, DMA_IN_DONE */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE));
|
||||
|
||||
/* Check for the absence of error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
if(process != NULL) {
|
||||
crypto_register_process_notification(process);
|
||||
nvic_interrupt_unpend(NVIC_INT_AES);
|
||||
nvic_interrupt_enable(NVIC_INT_AES);
|
||||
}
|
||||
|
||||
/* Enable result available bit in interrupt enable */
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
if(pdata_len != 0) {
|
||||
/* Configure DMAC
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the payload data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)cdata;
|
||||
/* Payload data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = pdata_len;
|
||||
|
||||
/* Enable DMA channel 1 */
|
||||
REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the output data buffer */
|
||||
REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)cdata;
|
||||
/* Output data length in bytes */
|
||||
REG(AES_DMAC_CH1_DMALENGTH) = pdata_len;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_decrypt_check_status(void)
|
||||
{
|
||||
/* Check if result is available or some error has occured */
|
||||
return ccm_auth_encrypt_check_status();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len,
|
||||
void *mic, uint8_t mic_len)
|
||||
{
|
||||
uint32_t aes_ctrl_int_stat;
|
||||
uint16_t pdata_len = cdata_len - mic_len;
|
||||
uint32_t tag[4];
|
||||
|
||||
aes_ctrl_int_stat = REG(AES_CTRL_INT_STAT);
|
||||
/* Clear the error bits */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR |
|
||||
AES_CTRL_INT_CLR_KEY_ST_WR_ERR |
|
||||
AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
|
||||
nvic_interrupt_disable(NVIC_INT_AES);
|
||||
crypto_register_process_notification(NULL);
|
||||
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
|
||||
if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) {
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Read tag
|
||||
* Wait for the context ready bit */
|
||||
while(!(REG(AES_AES_CTRL) & AES_AES_CTRL_SAVED_CONTEXT_READY));
|
||||
|
||||
/* Read the tag registers */
|
||||
tag[0] = REG(AES_AES_TAG_OUT_0);
|
||||
tag[1] = REG(AES_AES_TAG_OUT_1);
|
||||
tag[2] = REG(AES_AES_TAG_OUT_2);
|
||||
tag[3] = REG(AES_AES_TAG_OUT_3);
|
||||
|
||||
/* Clear the interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Check MIC */
|
||||
if(rom_util_memcmp(tag, &((const uint8_t *)cdata)[pdata_len], mic_len)) {
|
||||
return CCM_AUTHENTICATION_FAILED;
|
||||
}
|
||||
|
||||
/* Copy tag to MIC */
|
||||
rom_util_memcpy(mic, tag, mic_len);
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/** @} */
|
141
cpu/cc2538/dev/ccm.h
Normal file
141
cpu/cc2538/dev/ccm.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-aes
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ccm cc2538 AES-CCM
|
||||
*
|
||||
* Driver for the cc2538 AES-CCM mode of the security core
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 AES-CCM driver
|
||||
*/
|
||||
#ifndef CCM_H_
|
||||
#define CCM_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/aes.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES-CCM driver return codes
|
||||
* @{
|
||||
*/
|
||||
#define CCM_AUTHENTICATION_FAILED 7
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES-CCM functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Starts the CCM authentication and encryption operation
|
||||
* \param len_len Number of octets in length field (2, 4 or 8)
|
||||
* \param key_area Area in Key RAM where the key is stored (0 to 7)
|
||||
* \param nonce Pointer to nonce (15 - \p len_len octets)
|
||||
* \param adata Pointer to additional authenticated data, or \c NULL
|
||||
* \param adata_len Length of additional authenticated data in octets, or \c 0
|
||||
* \param pdata Pointer to message to authenticate and encrypt, or \c NULL
|
||||
* \param pdata_len Length of message to authenticate and encrypt in octets, or \c 0
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \param process Process to be polled upon completion of the operation, or \c NULL
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
*/
|
||||
uint8_t ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area,
|
||||
const void *nonce, const void *adata,
|
||||
uint16_t adata_len, void *pdata,
|
||||
uint16_t pdata_len, uint8_t mic_len,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Checks the status of the CCM authentication and encryption operation
|
||||
* \retval false Result not yet available, and no error occurred
|
||||
* \retval true Result available, or error occurred
|
||||
*/
|
||||
uint8_t ccm_auth_encrypt_check_status(void);
|
||||
|
||||
/** \brief Gets the result of the CCM authentication and encryption operation
|
||||
* \param mic Pointer to authentication field, or \c NULL
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
* \note This function must be called only after \c ccm_auth_encrypt_start().
|
||||
*/
|
||||
uint8_t ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len);
|
||||
|
||||
/** \brief Starts the CCM authentication checking and decryption operation
|
||||
* \param len_len Number of octets in length field (2, 4 or 8)
|
||||
* \param key_area Area in Key RAM where the key is stored (0 to 7)
|
||||
* \param nonce Pointer to nonce (15 - \p len_len octets)
|
||||
* \param adata Pointer to additional authenticated data, or \c NULL
|
||||
* \param adata_len Length of additional authenticated data in octets, or \c 0
|
||||
* \param cdata Pointer to encrypted and authenticated message
|
||||
* \param cdata_len Length of encrypted and authenticated message in octets
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \param process Process to be polled upon completion of the operation, or \c NULL
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
*/
|
||||
uint8_t ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area,
|
||||
const void *nonce, const void *adata,
|
||||
uint16_t adata_len, void *cdata,
|
||||
uint16_t cdata_len, uint8_t mic_len,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Checks the status of the CCM authentication checking and decryption operation
|
||||
* \retval false Result not yet available, and no error occurred
|
||||
* \retval true Result available, or error occurred
|
||||
*/
|
||||
uint8_t ccm_auth_decrypt_check_status(void);
|
||||
|
||||
/** \brief Gets the result of the CCM authentication checking and decryption operation
|
||||
* \param cdata Pointer to encrypted and authenticated message
|
||||
* \param cdata_len Length of encrypted and authenticated message in octets
|
||||
* \param mic Pointer to authentication field, or \c NULL
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
* \note This function must be called only after \c ccm_auth_decrypt_start().
|
||||
*/
|
||||
uint8_t ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len,
|
||||
void *mic, uint8_t mic_len);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* CCM_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
120
cpu/cc2538/dev/crypto.c
Normal file
120
cpu/cc2538/dev/crypto.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-crypto
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 AES/SHA cryptoprocessor driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/energest.h"
|
||||
#include "dev/sys-ctrl.h"
|
||||
#include "dev/nvic.h"
|
||||
#include "dev/crypto.h"
|
||||
#include "dev/aes.h"
|
||||
#include "reg.h"
|
||||
#include "lpm.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static volatile struct process *notification_process = NULL;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief The AES/SHA cryptoprocessor ISR
|
||||
*
|
||||
* This is the interrupt service routine for the AES/SHA
|
||||
* cryptoprocessor.
|
||||
*
|
||||
* This ISR is called at worst from PM0, so lpm_exit() does not need
|
||||
* to be called.
|
||||
*/
|
||||
void
|
||||
crypto_isr(void)
|
||||
{
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
|
||||
nvic_interrupt_unpend(NVIC_INT_AES);
|
||||
nvic_interrupt_disable(NVIC_INT_AES);
|
||||
|
||||
if(notification_process != NULL) {
|
||||
process_poll((struct process *)notification_process);
|
||||
notification_process = NULL;
|
||||
}
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
permit_pm1(void)
|
||||
{
|
||||
return REG(AES_CTRL_ALG_SEL) == 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
crypto_init(void)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
lpm_register_peripheral(permit_pm1);
|
||||
|
||||
crypto_enable();
|
||||
|
||||
/* Reset the AES/SHA cryptoprocessor */
|
||||
REG(SYS_CTRL_SRSEC) |= SYS_CTRL_SRSEC_AES;
|
||||
for(i = 0; i < 16; i++);
|
||||
REG(SYS_CTRL_SRSEC) &= ~SYS_CTRL_SRSEC_AES;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
crypto_enable(void)
|
||||
{
|
||||
/* Enable the clock for the AES/SHA cryptoprocessor */
|
||||
REG(SYS_CTRL_RCGCSEC) |= SYS_CTRL_RCGCSEC_AES;
|
||||
REG(SYS_CTRL_SCGCSEC) |= SYS_CTRL_SCGCSEC_AES;
|
||||
REG(SYS_CTRL_DCGCSEC) |= SYS_CTRL_DCGCSEC_AES;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
crypto_disable(void)
|
||||
{
|
||||
/* Gate the clock for the AES/SHA cryptoprocessor */
|
||||
REG(SYS_CTRL_RCGCSEC) &= ~SYS_CTRL_RCGCSEC_AES;
|
||||
REG(SYS_CTRL_SCGCSEC) &= ~SYS_CTRL_SCGCSEC_AES;
|
||||
REG(SYS_CTRL_DCGCSEC) &= ~SYS_CTRL_DCGCSEC_AES;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
crypto_register_process_notification(struct process *p)
|
||||
{
|
||||
notification_process = p;
|
||||
}
|
||||
|
||||
/** @} */
|
89
cpu/cc2538/dev/crypto.h
Normal file
89
cpu/cc2538/dev/crypto.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-crypto cc2538 AES/SHA cryptoprocessor
|
||||
*
|
||||
* Driver for the cc2538 AES/SHA cryptoprocessor
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 AES/SHA cryptoprocessor driver
|
||||
*/
|
||||
#ifndef CRYPTO_H_
|
||||
#define CRYPTO_H_
|
||||
|
||||
#include "contiki.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Crypto drivers return codes
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_SUCCESS 0
|
||||
#define CRYPTO_INVALID_PARAM 1
|
||||
#define CRYPTO_NULL_ERROR 2
|
||||
#define CRYPTO_RESOURCE_IN_USE 3
|
||||
#define CRYPTO_DMA_BUS_ERROR 4
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Crypto functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Enables and resets the AES/SHA cryptoprocessor
|
||||
*/
|
||||
void crypto_init(void);
|
||||
|
||||
/** \brief Enables the AES/SHA cryptoprocessor
|
||||
*/
|
||||
void crypto_enable(void);
|
||||
|
||||
/** \brief Disables the AES/SHA cryptoprocessor
|
||||
* \note Call this function to save power when the cryptoprocessor is unused.
|
||||
*/
|
||||
void crypto_disable(void);
|
||||
|
||||
/** \brief Registers a process to be notified of the completion of a crypto
|
||||
* operation
|
||||
* \param p Process to be polled upon IRQ
|
||||
* \note This function is only supposed to be called by the crypto drivers.
|
||||
*/
|
||||
void crypto_register_process_notification(struct process *p);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* CRYPTO_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
356
cpu/cc2538/dev/sha256.c
Normal file
356
cpu/cc2538/dev/sha256.c
Normal file
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-sha256
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 SHA-256 driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/aes.h"
|
||||
#include "dev/sha256.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BLOCK_SIZE 64
|
||||
#define OUTPUT_LEN 32
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Starts a new hash session in hardware
|
||||
* \param state Hash state
|
||||
* \param data Pointer to input message
|
||||
* \param hash Destination of the hash (32 bytes)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
*/
|
||||
static uint8_t
|
||||
new_hash(sha256_state_t *state, const void *data, void *hash)
|
||||
{
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
/* Configure master control module and enable DMA path to the SHA-256 engine
|
||||
* + Digest readout */
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_TAG | AES_CTRL_ALG_SEL_HASH;
|
||||
|
||||
/* Clear any outstanding events */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Configure hash engine
|
||||
* Indicate start of a new hash session and SHA-256 */
|
||||
REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE |
|
||||
AES_HASH_MODE_IN_NEW_HASH;
|
||||
|
||||
/* If the final digest is required (pad the input DMA data), write the
|
||||
* following register */
|
||||
if(state->final_digest) {
|
||||
/* Write length of the message (lo) */
|
||||
REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length;
|
||||
/* Write length of the message (hi) */
|
||||
REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32);
|
||||
/* Pad the DMA-ed data */
|
||||
REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE;
|
||||
}
|
||||
|
||||
/* Enable DMA channel 0 for message data */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data;
|
||||
if(state->final_digest) {
|
||||
/* Input data length in bytes, equal to the message */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = state->curlen;
|
||||
} else {
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Enable DMA channel 1 for result digest */
|
||||
REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the digest buffer */
|
||||
REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)hash;
|
||||
/* Length of the result digest */
|
||||
REG(AES_DMAC_CH1_DMALENGTH) = OUTPUT_LEN;
|
||||
|
||||
/* Wait for completion of the operation */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV));
|
||||
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
|
||||
/* Clear the interrupt */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
/* Clear mode */
|
||||
REG(AES_AES_CTRL) = 0x00000000;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Resumes an already started hash session in hardware
|
||||
* \param state Hash state
|
||||
* \param data Pointer to the input message
|
||||
* \param hash Pointer to the destination of the hash (32 bytes)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
*/
|
||||
static uint8_t
|
||||
resume_hash(sha256_state_t *state, const void *data, void *hash)
|
||||
{
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
/* Configure master control module and enable the DMA path to the SHA-256
|
||||
* engine */
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_HASH;
|
||||
|
||||
/* Clear any outstanding events */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Configure hash engine
|
||||
* Indicate the start of a resumed hash session and SHA-256 */
|
||||
REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE;
|
||||
|
||||
/* If the final digest is required (pad the input DMA data) */
|
||||
if(state->final_digest) {
|
||||
/* Write length of the message (lo) */
|
||||
REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length;
|
||||
/* Write length of the message (hi) */
|
||||
REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32);
|
||||
}
|
||||
|
||||
/* Write the initial digest */
|
||||
REG(AES_HASH_DIGEST_A) = (uint32_t)state->state[0];
|
||||
REG(AES_HASH_DIGEST_B) = (uint32_t)state->state[1];
|
||||
REG(AES_HASH_DIGEST_C) = (uint32_t)state->state[2];
|
||||
REG(AES_HASH_DIGEST_D) = (uint32_t)state->state[3];
|
||||
REG(AES_HASH_DIGEST_E) = (uint32_t)state->state[4];
|
||||
REG(AES_HASH_DIGEST_F) = (uint32_t)state->state[5];
|
||||
REG(AES_HASH_DIGEST_G) = (uint32_t)state->state[6];
|
||||
REG(AES_HASH_DIGEST_H) = (uint32_t)state->state[7];
|
||||
|
||||
/* If final digest, pad the DMA-ed data */
|
||||
if(state->final_digest) {
|
||||
REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE;
|
||||
}
|
||||
|
||||
/* Enable DMA channel 0 for message data */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data;
|
||||
/* Input data length in bytes, equal to the message */
|
||||
if(state->final_digest) {
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = state->curlen;
|
||||
} else {
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Wait for completion of the operation */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV));
|
||||
|
||||
/* Check for any DMA Bus errors */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
|
||||
/* Read digest */
|
||||
((uint32_t *)hash)[0] = REG(AES_HASH_DIGEST_A);
|
||||
((uint32_t *)hash)[1] = REG(AES_HASH_DIGEST_B);
|
||||
((uint32_t *)hash)[2] = REG(AES_HASH_DIGEST_C);
|
||||
((uint32_t *)hash)[3] = REG(AES_HASH_DIGEST_D);
|
||||
((uint32_t *)hash)[4] = REG(AES_HASH_DIGEST_E);
|
||||
((uint32_t *)hash)[5] = REG(AES_HASH_DIGEST_F);
|
||||
((uint32_t *)hash)[6] = REG(AES_HASH_DIGEST_G);
|
||||
((uint32_t *)hash)[7] = REG(AES_HASH_DIGEST_H);
|
||||
|
||||
/* Acknowledge reading of the digest */
|
||||
REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_OUTPUT_FULL;
|
||||
|
||||
/* Clear the interrupt */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
/* Clear mode */
|
||||
REG(AES_AES_CTRL) = 0x00000000;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
sha256_init(sha256_state_t *state)
|
||||
{
|
||||
if(state == NULL) {
|
||||
return CRYPTO_NULL_ERROR;
|
||||
}
|
||||
|
||||
state->curlen = 0;
|
||||
state->length = 0;
|
||||
state->new_digest = true;
|
||||
state->final_digest = false;
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
sha256_process(sha256_state_t *state, const void *data, uint32_t len)
|
||||
{
|
||||
uint32_t n;
|
||||
uint8_t ret;
|
||||
|
||||
if(state == NULL || data == NULL) {
|
||||
return CRYPTO_NULL_ERROR;
|
||||
}
|
||||
|
||||
if(state->curlen > sizeof(state->buf)) {
|
||||
return CRYPTO_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if(REG(AES_CTRL_ALG_SEL) != 0x00000000) {
|
||||
return CRYPTO_RESOURCE_IN_USE;
|
||||
}
|
||||
|
||||
if(len > 0 && state->new_digest) {
|
||||
if(state->curlen == 0 && len > BLOCK_SIZE) {
|
||||
rom_util_memcpy(state->buf, data, BLOCK_SIZE);
|
||||
ret = new_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->new_digest = false;
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
data += BLOCK_SIZE;
|
||||
len -= BLOCK_SIZE;
|
||||
} else {
|
||||
n = MIN(len, BLOCK_SIZE - state->curlen);
|
||||
rom_util_memcpy(&state->buf[state->curlen], data, n);
|
||||
state->curlen += n;
|
||||
data += n;
|
||||
len -= n;
|
||||
if(state->curlen == BLOCK_SIZE && len > 0) {
|
||||
ret = new_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->new_digest = false;
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
state->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(len > 0 && !state->new_digest) {
|
||||
if(state->curlen == 0 && len > BLOCK_SIZE) {
|
||||
rom_util_memcpy(state->buf, data, BLOCK_SIZE);
|
||||
ret = resume_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
data += BLOCK_SIZE;
|
||||
len -= BLOCK_SIZE;
|
||||
} else {
|
||||
n = MIN(len, BLOCK_SIZE - state->curlen);
|
||||
rom_util_memcpy(&state->buf[state->curlen], data, n);
|
||||
state->curlen += n;
|
||||
data += n;
|
||||
len -= n;
|
||||
if(state->curlen == BLOCK_SIZE && len > 0) {
|
||||
ret = resume_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
state->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
sha256_done(sha256_state_t *state, void *hash)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
if(state == NULL || hash == NULL) {
|
||||
return CRYPTO_NULL_ERROR;
|
||||
}
|
||||
|
||||
if(state->curlen > sizeof(state->buf)) {
|
||||
return CRYPTO_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if(REG(AES_CTRL_ALG_SEL) != 0x00000000) {
|
||||
return CRYPTO_RESOURCE_IN_USE;
|
||||
}
|
||||
|
||||
/* Increase the length of the message */
|
||||
state->length += state->curlen << 3;
|
||||
state->final_digest = true;
|
||||
if(state->new_digest) {
|
||||
ret = new_hash(state, state->buf, hash);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = resume_hash(state, state->buf, hash);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
state->new_digest = false;
|
||||
state->final_digest = false;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/** @} */
|
103
cpu/cc2538/dev/sha256.h
Normal file
103
cpu/cc2538/dev/sha256.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-crypto
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-sha526 cc2538 SHA-256
|
||||
*
|
||||
* Driver for the cc2538 SHA-256 mode of the security core
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 SHA-256 driver
|
||||
*/
|
||||
#ifndef SHA256_H_
|
||||
#define SHA256_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/crypto.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SHA-256 structures
|
||||
* @{
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t length;
|
||||
uint32_t state[8];
|
||||
uint32_t curlen;
|
||||
uint8_t buf[64];
|
||||
uint8_t new_digest;
|
||||
uint8_t final_digest;
|
||||
} sha256_state_t;
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SHA-256 functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Initializes the hash state
|
||||
* \param state Pointer to hash state to initialize
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
*/
|
||||
uint8_t sha256_init(sha256_state_t *state);
|
||||
|
||||
/** \brief Processes a block of memory through the hash
|
||||
* \param state Pointer to hash state
|
||||
* \param data Pointer to the data to hash
|
||||
* \param len Length of the data to hash in bytes (octets)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
* \note This function must be called only after \c sha256_init().
|
||||
*/
|
||||
uint8_t sha256_process(sha256_state_t *state, const void *data, uint32_t len);
|
||||
|
||||
/** \brief Terminates hash session to get the digest
|
||||
* \param state Pointer to hash state
|
||||
* \param hash Pointer to hash
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
* \note This function must be called only after \c sha256_process().
|
||||
*/
|
||||
uint8_t sha256_done(sha256_state_t *state, void *hash);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* SHA256_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -161,6 +161,34 @@
|
|||
#define SYS_CTRL_SRGPT_GPT0 0x00000001 /**< GPT0 is reset */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_RCGCSEC register bit masks
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_RCGCSEC_AES 0x00000002 /**< AES clock enable, CPU running */
|
||||
#define SYS_CTRL_RCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU running */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_SCGCSEC register bit masks
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_SCGCSEC_AES 0x00000002 /**< AES clock enable, CPU IDLE */
|
||||
#define SYS_CTRL_SCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU IDLE */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_DCGCSEC register bit masks
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_DCGCSEC_AES 0x00000002 /**< AES clock enable, PM0 */
|
||||
#define SYS_CTRL_DCGCSEC_PKA 0x00000001 /**< PKA clock enable, PM0 */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_SRSEC register bits
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_SRSEC_AES 0x00000002 /**< AES is reset */
|
||||
#define SYS_CTRL_SRSEC_PKA 0x00000001 /**< PKA is reset */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_PWRDBG register bits
|
||||
* @{
|
||||
*/
|
||||
|
|
|
@ -359,7 +359,7 @@ uart_write_byte(uint8_t uart, uint8_t b)
|
|||
REG(uart_base + UART_DR) = b;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
static void
|
||||
uart_isr(uint8_t uart)
|
||||
{
|
||||
uint32_t uart_base;
|
||||
|
|
|
@ -88,15 +88,6 @@ watchdog_periodic(void)
|
|||
REG(SMWDTHROSC_WDCTL) = (SMWDTHROSC_WDCTL_CLR_2 | SMWDTHROSC_WDCTL_CLR_0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief In watchdog mode, the WDT can not be stopped. This function is
|
||||
* defined here to satisfy API requirements.
|
||||
*/
|
||||
void
|
||||
watchdog_stop(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Keeps control until the WDT throws a reset signal. Starts the WDT
|
||||
* if not already started. */
|
||||
void
|
||||
|
|
|
@ -101,7 +101,7 @@ static uint8_t max_pm;
|
|||
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||
#else
|
||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 2
|
||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 3
|
||||
#endif
|
||||
|
||||
static lpm_periph_permit_pm1_func_t
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "reg.h"
|
||||
#include "flash-cca.h"
|
||||
#include "sys-ctrl.h"
|
||||
#include "rom-util.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -66,6 +67,7 @@ void udma_err_isr(void);
|
|||
void usb_isr(void) WEAK_ALIAS(default_handler);
|
||||
void uart0_isr(void) WEAK_ALIAS(default_handler);
|
||||
void uart1_isr(void) WEAK_ALIAS(default_handler);
|
||||
void crypto_isr(void);
|
||||
|
||||
/* Boot Loader Backdoor selection */
|
||||
#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR
|
||||
|
@ -89,7 +91,7 @@ void uart1_isr(void) WEAK_ALIAS(default_handler);
|
|||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Allocate stack space */
|
||||
static unsigned long stack[512];
|
||||
static unsigned long stack[512] __attribute__ ((section(".stack")));
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Linker construct indicating .text section location */
|
||||
extern uint8_t _text[0];
|
||||
|
@ -268,18 +270,18 @@ void(*const vectors[])(void) =
|
|||
usb_isr, /* 156 USB */
|
||||
cc2538_rf_rx_tx_isr, /* 157 RFCORE RX/TX */
|
||||
cc2538_rf_err_isr, /* 158 RFCORE Error */
|
||||
default_handler, /* 159 AES */
|
||||
crypto_isr, /* 159 AES */
|
||||
default_handler, /* 160 PKA */
|
||||
rtimer_isr, /* 161 SM Timer */
|
||||
default_handler, /* 162 MACTimer */
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Linker constructs indicating .data and .bss segment locations */
|
||||
extern unsigned long _etext;
|
||||
extern unsigned long _data;
|
||||
extern unsigned long _edata;
|
||||
extern unsigned long _bss;
|
||||
extern unsigned long _ebss;
|
||||
extern uint8_t _ldata;
|
||||
extern uint8_t _data;
|
||||
extern uint8_t _edata;
|
||||
extern uint8_t _bss;
|
||||
extern uint8_t _ebss;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Weak interrupt handlers. */
|
||||
void
|
||||
|
@ -298,26 +300,13 @@ default_handler(void)
|
|||
void
|
||||
reset_handler(void)
|
||||
{
|
||||
unsigned long *pul_src, *pul_dst;
|
||||
|
||||
REG(SYS_CTRL_EMUOVR) = 0xFF;
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM. */
|
||||
pul_src = &_etext;
|
||||
|
||||
for(pul_dst = &_data; pul_dst < &_edata;) {
|
||||
*pul_dst++ = *pul_src++;
|
||||
}
|
||||
rom_util_memcpy(&_data, &_ldata, &_edata - &_data);
|
||||
|
||||
/* Zero-fill the bss segment. */
|
||||
__asm(" ldr r0, =_bss\n"
|
||||
" ldr r1, =_ebss\n"
|
||||
" mov r2, #0\n"
|
||||
" .thumb_func\n"
|
||||
"zero_loop:\n"
|
||||
" cmp r0, r1\n"
|
||||
" it lt\n"
|
||||
" strlt r2, [r0], #4\n" " blt zero_loop");
|
||||
rom_util_memset(&_bss, 0, &_ebss - &_bss);
|
||||
|
||||
/* call the application's entry point. */
|
||||
main();
|
||||
|
|
|
@ -872,7 +872,7 @@ fill_buffers(usb_buffer *buffer, uint8_t hw_ep, unsigned int len,
|
|||
static uint8_t
|
||||
ep0_get_setup_pkt(void)
|
||||
{
|
||||
uint8_t res;
|
||||
uint8_t res = 0;
|
||||
usb_buffer *buffer =
|
||||
skip_buffers_until(usb_endpoints[0].buffer, USB_BUFFER_SETUP,
|
||||
USB_BUFFER_SETUP, &res);
|
||||
|
@ -916,8 +916,6 @@ ep0_get_data_pkt(void)
|
|||
}
|
||||
|
||||
if(buffer->flags & (USB_BUFFER_SETUP | USB_BUFFER_IN)) {
|
||||
uint8_t temp;
|
||||
|
||||
buffer->flags |= USB_BUFFER_FAILED;
|
||||
buffer->flags &= ~USB_BUFFER_SUBMITTED;
|
||||
if(buffer->flags & USB_BUFFER_NOTIFY) {
|
||||
|
@ -925,7 +923,7 @@ ep0_get_data_pkt(void)
|
|||
}
|
||||
/* Flush the fifo */
|
||||
while(len--) {
|
||||
temp = REG(USB_F0);
|
||||
REG(USB_F0);
|
||||
}
|
||||
usb_endpoints[0].buffer = buffer->next;
|
||||
/* Force data stage end */
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
/* In watchdog mode, our WDT can't be stopped once started
|
||||
* Include watchdog_stop()'s declaration and then trash it */
|
||||
#include "dev/watchdog.h"
|
||||
#define watchdog_stop() watchdog_periodic()
|
||||
|
||||
/* This port no longer implements the legacy clock_delay. Hack its usages
|
||||
* outta the way till it gets phased out completely
|
||||
* NB: This also overwrites the prototype so delay_usec() is declared twice */
|
||||
|
|
|
@ -486,7 +486,7 @@ transmit(unsigned short transmit_len)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
send(void *payload, unsigned short payload_len)
|
||||
send(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
prepare(payload, payload_len);
|
||||
return transmit(payload_len);
|
||||
|
|
7
cpu/cc26xx-cc13xx/Makefile.cc13xx
Normal file
7
cpu/cc26xx-cc13xx/Makefile.cc13xx
Normal file
|
@ -0,0 +1,7 @@
|
|||
TI_XXWARE_PATH = lib/cc13xxware
|
||||
|
||||
CONTIKI_CPU_SOURCEFILES += smartrf-settings.c prop-mode.c
|
||||
|
||||
CFLAGS += -DCPU_FAMILY_CC13XX=1
|
||||
|
||||
include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx
|
3
cpu/cc26xx-cc13xx/Makefile.cc26xx
Normal file
3
cpu/cc26xx-cc13xx/Makefile.cc26xx
Normal file
|
@ -0,0 +1,3 @@
|
|||
TI_XXWARE_PATH = lib/cc26xxware
|
||||
|
||||
include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx
|
|
@ -8,25 +8,24 @@ NM = arm-none-eabi-nm
|
|||
SIZE = arm-none-eabi-size
|
||||
SREC_CAT = srec_cat
|
||||
|
||||
CPU_ABS_PATH = cpu/cc26xx
|
||||
TI_CC26XXWARE_PATH = lib/cc26xxware
|
||||
TI_CC26XXWARE = $(CONTIKI_CPU)/$(TI_CC26XXWARE_PATH)
|
||||
CPU_ABS_PATH = cpu/cc26xx-cc13xx
|
||||
TI_XXWARE = $(CONTIKI_CPU)/$(TI_XXWARE_PATH)
|
||||
|
||||
### cc26xxware sources under driverlib will be added to the MODULES list
|
||||
TI_CC26XXWARE_SRC = $(CPU_ABS_PATH)/$(TI_CC26XXWARE_PATH)/driverlib
|
||||
TI_XXWARE_SRC = $(CPU_ABS_PATH)/$(TI_XXWARE_PATH)/driverlib
|
||||
|
||||
### The directory with startup sources will be added to the CONTIKI_CPU_DIRS
|
||||
### and the sources therein are added to the sources list explicitly. They are
|
||||
### also listed explicitly in the linker command (through TARGET_STARTFILES),
|
||||
### to make sure they always get linked in the image
|
||||
TI_CC26XXWARE_STARTUP_DIR = $(TI_CC26XXWARE_PATH)/startup_files
|
||||
TI_CC26XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c
|
||||
TI_XXWARE_STARTUP_DIR = $(TI_XXWARE_PATH)/startup_files
|
||||
TI_XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c
|
||||
|
||||
### MODULES will add some of these to the include path, but we need to add
|
||||
### them earlier to prevent filename clashes with Contiki core files
|
||||
CFLAGS += -I$(TI_CC26XXWARE) -I$(CONTIKI)/$(TI_CC26XXWARE_SRC)
|
||||
CFLAGS += -I$(TI_CC26XXWARE)/inc
|
||||
MODULES += $(TI_CC26XXWARE_SRC)
|
||||
CFLAGS += -I$(TI_XXWARE) -I$(CONTIKI)/$(TI_XXWARE_SRC)
|
||||
CFLAGS += -I$(TI_XXWARE)/inc
|
||||
MODULES += $(TI_XXWARE_SRC)
|
||||
|
||||
LDSCRIPT = $(CONTIKI_CPU)/cc26xx.ld
|
||||
|
||||
|
@ -35,10 +34,6 @@ CFLAGS += -ffunction-sections -fdata-sections
|
|||
CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing
|
||||
CFLAGS += -Wall -std=c99
|
||||
|
||||
### Workaround for driverlib's cpu.h which tests if defined(gcc)
|
||||
### Delete if it gets fixed or if we stop using the driverlib
|
||||
CFLAGS += -Dgcc=__GNUC__
|
||||
|
||||
LDFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian -nostartfiles
|
||||
LDFLAGS += -T $(LDSCRIPT)
|
||||
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
||||
|
@ -62,23 +57,24 @@ endif
|
|||
CLEAN += symbols.c symbols.h *.d *.elf *.hex
|
||||
|
||||
### CPU-dependent directories
|
||||
CONTIKI_CPU_DIRS = . dev dev/rfc-api $(TI_CC26XXWARE_STARTUP_DIR)
|
||||
CONTIKI_CPU_DIRS = . dev rf-core rf-core/api $(TI_XXWARE_STARTUP_DIR)
|
||||
|
||||
### Use the existing debug I/O in cpu/arm/common
|
||||
CONTIKI_CPU_DIRS += ../arm/common/dbg-io
|
||||
|
||||
### CPU-dependent source files
|
||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c cc26xx-rtc.c uart.c
|
||||
CONTIKI_CPU_SOURCEFILES += cc26xx-rf.c contiki-watchdog.c
|
||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c
|
||||
CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c
|
||||
CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c
|
||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c
|
||||
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c
|
||||
CONTIKI_CPU_SOURCEFILES += rf-core.c rf-ble.c ieee-mode.c
|
||||
|
||||
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
|
||||
|
||||
CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES)
|
||||
|
||||
TARGET_START_SOURCEFILES += fault-handlers.c $(TI_CC26XXWARE_STARTUP_SRCS)
|
||||
TARGET_START_SOURCEFILES += fault-handlers.c $(TI_XXWARE_STARTUP_SRCS)
|
||||
TARGET_STARTFILES = $(addprefix $(OBJECTDIR)/,$(call oname, $(TARGET_START_SOURCEFILES)))
|
||||
|
||||
### Don't treat the .elf as intermediate
|
|
@ -44,8 +44,11 @@ MEMORY
|
|||
*/
|
||||
FLASH_CCFG (RX) : ORIGIN = 0x0001FFA8, LENGTH = 88
|
||||
|
||||
/* RAM Size 20KB (PG2.1) */
|
||||
/* RAM Size 20KB */
|
||||
SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00005000
|
||||
|
||||
/* Application can use GPRAM region as RAM if cache is disabled in CCFG */
|
||||
GPRAM (RWX) : ORIGIN = 0x11000000, LENGTH = 0x00002000
|
||||
}
|
||||
|
||||
/*. Highest address of the stack. Used in startup file .*/
|
||||
|
@ -100,4 +103,9 @@ SECTIONS
|
|||
. = . + _Min_Stack_Size;
|
||||
. = ALIGN(4);
|
||||
} > SRAM
|
||||
|
||||
.gpram :
|
||||
{
|
||||
} > GPRAM
|
||||
|
||||
}
|
|
@ -35,30 +35,35 @@
|
|||
* \defgroup cc26xx-platforms TI CC26xx-powered Platforms
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx The TI CC26xx CPU
|
||||
* \defgroup cc26xx The TI CC26xx and CC13xx CPUs
|
||||
*
|
||||
* This group documents the TI CC26xx and CC13xx CPUs. The two CPU families are
|
||||
* very similar, with the main difference being related to radio capability.
|
||||
*
|
||||
* Documentation in this group should be considered to be applicable to both
|
||||
* families, unless explicitly stated otherwise.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \addtogroup cc26xx-clocks
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-software-clock CC26xx Software Clock
|
||||
* \defgroup cc26xx-software-clock Software Clock
|
||||
*
|
||||
* Implementation of the clock module for the cc26xx.
|
||||
* Implementation of the clock module for the CC26xx and CC13xx.
|
||||
*
|
||||
* The software clock uses the facilities provided by the AON RTC driver
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Software clock implementation for the TI CC26xx
|
||||
* Software clock implementation for the TI CC13xx/CC26xx
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static volatile clock_time_t count;
|
||||
static volatile clock_time_t second_countdown;
|
||||
static volatile unsigned long secs;
|
||||
static volatile uint64_t count;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
power_domain_on(void)
|
||||
|
@ -72,8 +77,6 @@ void
|
|||
clock_init(void)
|
||||
{
|
||||
count = 0;
|
||||
secs = 0;
|
||||
second_countdown = CLOCK_SECOND;
|
||||
|
||||
/*
|
||||
* Here, we configure GPT0 Timer A, which we subsequently use in
|
||||
|
@ -120,33 +123,50 @@ clock_init(void)
|
|||
CCIF clock_time_t
|
||||
clock_time(void)
|
||||
{
|
||||
return count;
|
||||
return (clock_time_t)(count & 0xFFFFFFFF);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
clock_update(void)
|
||||
{
|
||||
count++;
|
||||
bool interrupts_disabled;
|
||||
uint32_t aon_rtc_secs_now;
|
||||
uint16_t aon_rtc_ticks_now;
|
||||
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC);
|
||||
aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16;
|
||||
|
||||
/* Convert AON RTC ticks to clock tick counter */
|
||||
count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9);
|
||||
|
||||
/* Re-enable interrupts */
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
if(etimer_pending()) {
|
||||
etimer_request_poll();
|
||||
}
|
||||
|
||||
if(--second_countdown == 0) {
|
||||
secs++;
|
||||
second_countdown = CLOCK_SECOND;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
clock_set_seconds(unsigned long sec)
|
||||
{
|
||||
secs = sec;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF unsigned long
|
||||
clock_seconds(void)
|
||||
{
|
||||
return secs;
|
||||
bool interrupts_disabled;
|
||||
uint32_t secs_now;
|
||||
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
secs_now = ti_lib_aon_rtc_sec_get();
|
||||
|
||||
/* Re-enable interrupts */
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
return (unsigned long)secs_now;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
|
@ -32,13 +32,13 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-char-io CC26xx Character I/O
|
||||
* \defgroup cc26xx-char-io CC13xx/CC26xx Character I/O
|
||||
*
|
||||
* CC26xx CPU-specific functions for debugging and SLIP I/O
|
||||
* CC13xx/CC26xx CPU-specific functions for debugging and SLIP I/O
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC26xx Debug I/O module
|
||||
* Header file for the CC13xx/CC26xx Debug I/O module
|
||||
*/
|
||||
#ifndef DBG_H_
|
||||
#define DBG_H_
|
|
@ -33,7 +33,7 @@
|
|||
* @{
|
||||
*
|
||||
* \file
|
||||
* Driver for the CC26xx AON battery monitor
|
||||
* Driver for the CC13xx/CC26xx AON battery monitor
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
|
@ -32,13 +32,13 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-batmon CC26xx BatMon sensor driver
|
||||
* \defgroup cc26xx-batmon CC13xx/CC26xx BatMon sensor driver
|
||||
*
|
||||
* Driver for the on-chip battery voltage and chip temperature sensor.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC26xx battery monitor
|
||||
* Header file for the CC13xx/CC26xx battery monitor
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef BATMON_SENSOR_H_
|
|
@ -27,6 +27,15 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx-uart
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the CC13xx/CC26xx UART driver.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
||||
#include "cc26xx-uart.h"
|
||||
#include "hw_types.h"
|
||||
|
@ -41,6 +50,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Which events to trigger a UART interrupt */
|
||||
#define CC26XX_UART_RX_INTERRUPT_TRIGGERS (UART_INT_RX | UART_INT_RT)
|
||||
|
@ -382,3 +392,5 @@ cc26xx_uart_isr(void)
|
|||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -31,13 +31,13 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-uart CC26xx UARTs
|
||||
* \defgroup cc26xx-uart CC13xx/CC26xx UARTs
|
||||
*
|
||||
* Driver for the CC26xx UART controller
|
||||
* Driver for the CC13xx/CC26xx UART controller
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC26xx UART driver
|
||||
* Header file for the CC13xx/CC26xx UART driver
|
||||
*/
|
||||
#ifndef CC26XX_UART_H_
|
||||
#define CC26XX_UART_H_
|
|
@ -31,16 +31,16 @@
|
|||
* \addtogroup cc26xx-clocks
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-wdt CC26xx watchdog timer driver
|
||||
* \defgroup cc26xx-wdt CC13xx/CC26xx watchdog timer driver
|
||||
*
|
||||
* Driver for the CC26xx Watchdog Timer
|
||||
* Driver for the CC13xx/CC26xx Watchdog Timer
|
||||
*
|
||||
* This file is not called watchdog.c because the filename is in use by
|
||||
* TI CC26xxware
|
||||
* TI CC26xxware/CC13xxware
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc26xx watchdog driver.
|
||||
* Implementation of the CC13xx/CC26xx watchdog driver.
|
||||
*/
|
||||
#include "watchdog.h"
|
||||
#include "ti-lib.h"
|
||||
|
@ -75,14 +75,6 @@ watchdog_periodic(void)
|
|||
ti_lib_watchdog_int_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Stub function to satisfy API requirements
|
||||
*/
|
||||
void
|
||||
watchdog_stop(void)
|
||||
{
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Manually trigger a WDT reboot
|
||||
*/
|
|
@ -28,6 +28,14 @@
|
|||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx-gpio-interrupts
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of CC13xx/CC26xx GPIO interrupt handling.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "ioc.h"
|
||||
#include "gpio-interrupt.h"
|
||||
#include "sys/energest.h"
|
||||
|
@ -94,4 +102,4 @@ gpio_interrupt_isr(void)
|
|||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
|
@ -32,15 +32,15 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-gpio-interrupts CC26xx GPIO interrupt handling
|
||||
* \defgroup cc26xx-gpio-interrupts CC13xx/CC26xx GPIO interrupt handling
|
||||
*
|
||||
* The CC26xx GPIO interrupt handler and an API which can be used by other
|
||||
* parts of the code when they wish to be notified of a GPIO interrupt
|
||||
* The CC13xx/CC26xx GPIO interrupt handler and an API which can be used by
|
||||
* other parts of the code when they wish to be notified of a GPIO interrupt
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC26xx GPIO interrupt management
|
||||
* Header file for the CC13xx/CC26xx GPIO interrupt management
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef GPIO_INTERRUPT_H_
|
|
@ -166,7 +166,4 @@ oscillators_switch_to_hf_rc(void)
|
|||
osc_interface_dis(smph_clk_state);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
/** @} */
|
|
@ -32,9 +32,9 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-oscillators CC26XX oscillator control
|
||||
* \defgroup cc26xx-oscillators CC13xx/CC26xx oscillator control
|
||||
*
|
||||
* Wrapper around those CC26xxware OSC functions that we need in Contiki.
|
||||
* Wrapper around CC26xxware/CC13xxware OSC functions that we need in Contiki.
|
||||
*
|
||||
* All CC26xxware OSC control requires access to the semaphore module within
|
||||
* AUX. Thus, in addition to enabling the oscillator interface, we need to
|
||||
|
@ -43,7 +43,7 @@
|
|||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC26XX oscillator control
|
||||
* Header file for the CC13xx/CC26xx oscillator control
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef OSCILLATORS_H_
|
|
@ -27,15 +27,15 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx-rtc
|
||||
* \addtogroup cc13xx-cc26xx-rtc
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Implementation of the CC26xx AON RTC driver
|
||||
* Implementation of the CC13xx/CC26xx AON RTC driver
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "sys/energest.h"
|
||||
#include "rtimer.h"
|
||||
|
@ -46,16 +46,31 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define cc26xx_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__)
|
||||
#define soc_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Prototype of a function in clock.c. Called every time the handler fires */
|
||||
void clock_update(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define COMPARE_INCREMENT (RTIMER_SECOND / CLOCK_SECOND)
|
||||
#define MULTIPLE_512_MASK 0xFFFFFE00
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Used to test timer wraparounds.
|
||||
*
|
||||
* Set to 0xFFFFFFFA to test AON RTC second counter wraparound
|
||||
* Set to 0xFFFA to test AON RTC 16.16 format wraparound
|
||||
*/
|
||||
#ifdef SOC_RTC_CONF_START_TICK_COUNT
|
||||
#define SOC_RTC_START_TICK_COUNT SOC_RTC_CONF_START_TICK_COUNT
|
||||
#else
|
||||
#define SOC_RTC_START_TICK_COUNT 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc26xx_rtc_init(void)
|
||||
soc_rtc_init(void)
|
||||
{
|
||||
uint32_t compare_value;
|
||||
bool interrupts_disabled;
|
||||
uint32_t next;
|
||||
|
||||
/* Disable and clear interrupts */
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
@ -63,22 +78,22 @@ cc26xx_rtc_init(void)
|
|||
ti_lib_aon_rtc_disable();
|
||||
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH2);
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH1);
|
||||
|
||||
/* Setup the wakeup event */
|
||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC0);
|
||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC2);
|
||||
ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH2);
|
||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC_CH0);
|
||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC_CH1);
|
||||
ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1);
|
||||
|
||||
/* Configure channel 2 in continuous compare, 128 ticks / sec */
|
||||
ti_lib_aon_rtc_inc_value_ch2_set(RTIMER_SECOND / CLOCK_SECOND);
|
||||
ti_lib_aon_rtc_mode_ch2_set(AON_RTC_MODE_CH2_CONTINUOUS);
|
||||
compare_value = (RTIMER_SECOND / CLOCK_SECOND) +
|
||||
ti_lib_aon_rtc_current_compare_value_get();
|
||||
ti_lib_aon_rtc_compare_value_set(AON_RTC_CH2, compare_value);
|
||||
HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = SOC_RTC_START_TICK_COUNT;
|
||||
|
||||
/* Enable channel 2 and the RTC */
|
||||
ti_lib_aon_rtc_channel_enable(AON_RTC_CH2);
|
||||
next = ti_lib_aon_rtc_current_compare_value_get() + COMPARE_INCREMENT;
|
||||
|
||||
/* Configure channel 1 to start generating clock ticks. First tick at 512 */
|
||||
ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next);
|
||||
|
||||
/* Enable channel 1 and the RTC */
|
||||
ti_lib_aon_rtc_channel_enable(AON_RTC_CH1);
|
||||
ti_lib_aon_rtc_enable();
|
||||
|
||||
ti_lib_int_enable(INT_AON_RTC);
|
||||
|
@ -90,41 +105,60 @@ cc26xx_rtc_init(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rtimer_clock_t
|
||||
cc26xx_rtc_get_next_trigger()
|
||||
soc_rtc_get_next_trigger()
|
||||
{
|
||||
rtimer_clock_t ch2 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH2);
|
||||
rtimer_clock_t ch1 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH1);
|
||||
|
||||
if(HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) & AON_RTC_CHCTL_CH0_EN) {
|
||||
rtimer_clock_t ch0 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH2);
|
||||
rtimer_clock_t ch0 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0);
|
||||
|
||||
return RTIMER_CLOCK_LT(ch0, ch2) ? ch0 : ch2;
|
||||
return RTIMER_CLOCK_LT(ch0, ch1) ? ch0 : ch1;
|
||||
}
|
||||
|
||||
return ch2;
|
||||
return ch1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc26xx_rtc_schedule_one_shot(uint32_t ticks)
|
||||
soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks)
|
||||
{
|
||||
if((channel != AON_RTC_CH0) && (channel != AON_RTC_CH1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the channel to fire a one-shot compare event at time==ticks */
|
||||
ti_lib_aon_rtc_compare_value_set(AON_RTC_CH0, ticks);
|
||||
ti_lib_aon_rtc_channel_enable(AON_RTC_CH0);
|
||||
ti_lib_aon_rtc_compare_value_set(channel, ticks);
|
||||
ti_lib_aon_rtc_channel_enable(channel);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* The AON RTC interrupt handler */
|
||||
void
|
||||
cc26xx_rtc_isr(void)
|
||||
soc_rtc_isr(void)
|
||||
{
|
||||
uint32_t now, next;
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
|
||||
if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) {
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
|
||||
rtimer_run_next();
|
||||
now = ti_lib_aon_rtc_current_compare_value_get();
|
||||
|
||||
/* Adjust the s/w tick counter irrespective of which event trigger this */
|
||||
clock_update();
|
||||
|
||||
if(ti_lib_aon_rtc_event_get(AON_RTC_CH1)) {
|
||||
HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH1;
|
||||
|
||||
/*
|
||||
* We need to keep ticking while we are awake, so we schedule the next
|
||||
* event on the next 512 tick boundary. If we drop to deep sleep before it
|
||||
* happens, lpm_drop() will reschedule us in the 'distant' future
|
||||
*/
|
||||
next = (now + COMPARE_INCREMENT) & MULTIPLE_512_MASK;
|
||||
ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next);
|
||||
}
|
||||
|
||||
if(ti_lib_aon_rtc_event_get(AON_RTC_CH2)) {
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH2);
|
||||
clock_update();
|
||||
if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) {
|
||||
ti_lib_aon_rtc_channel_disable(AON_RTC_CH0);
|
||||
HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH0;
|
||||
rtimer_run_next();
|
||||
}
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
|
@ -31,34 +31,28 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-clocks CC26xx clock and timer subsystem
|
||||
* \defgroup cc26xx-clocks CC13xx/CC26xx clock and timer subsystem
|
||||
*
|
||||
* For the CC26xx cpu we use the AON RTC as the basis for all clocks and timers
|
||||
* For the CC13xx/CC26xx cpu we use the AON RTC as the basis for all clocks and
|
||||
* timers
|
||||
*
|
||||
* We configure the AON RTC's channel 2 to run in continuous mode, generating
|
||||
* 128 interrupts / second. In continuous mode, the next compare event is
|
||||
* scheduled by the hardware automatically; the events are equidistant and
|
||||
* this also means we don't need the overhead of re-scheduling within the
|
||||
* interrupt handler
|
||||
*
|
||||
* For rtimers, we use the RTC's channel 0 in one-shot compare mode. When the
|
||||
* compare event fires, we call rtimer_run_next
|
||||
* We use two of the aviable AON RTC channels. Channel 0 is used by the rtimer
|
||||
* sub-system. Channel 1 is used by the system clock and the LPM module.
|
||||
*
|
||||
* The RTC runs in all power modes except 'shutdown'
|
||||
*
|
||||
* \sa cpu/cc26xx/clock.c cpu/cc26xx/rtimer-arch.c
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-rtc CC26xx AON RTC driver
|
||||
* \defgroup cc13xx-cc26xx-rtc CC13xx/CC26xx AON RTC driver
|
||||
*
|
||||
* Underpins the platform's software clocks and timers
|
||||
*
|
||||
* @{
|
||||
* \file
|
||||
* Header file for the CC26XX AON RTC driver
|
||||
* Header file for the CC13xx/CC26xx AON RTC driver
|
||||
*/
|
||||
#ifndef CC26XX_RTC_H_
|
||||
#define CC26XX_RTC_H_
|
||||
#ifndef SOC_RTC_H_
|
||||
#define SOC_RTC_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
|
||||
|
@ -67,12 +61,13 @@
|
|||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initialise the CC26XX AON RTC module
|
||||
* \brief Initialise the CC13XX/CC26XX AON RTC module
|
||||
*
|
||||
* This timer configures AON RTC channels.
|
||||
*
|
||||
* This timer configures the AON RTC's channel 2 to run in continuous mode
|
||||
* This function must be called before clock_init() and rtimer_init()
|
||||
*/
|
||||
void cc26xx_rtc_init(void);
|
||||
void soc_rtc_init(void);
|
||||
|
||||
/**
|
||||
* \brief Return the time of the next scheduled rtimer event
|
||||
|
@ -81,17 +76,24 @@ void cc26xx_rtc_init(void);
|
|||
* This function will check both AON RTC channels and will only take CH0's
|
||||
* compare into account if the channel is actually enabled
|
||||
*/
|
||||
rtimer_clock_t cc26xx_rtc_get_next_trigger(void);
|
||||
rtimer_clock_t soc_rtc_get_next_trigger(void);
|
||||
|
||||
/**
|
||||
* \brief Schedule an AON RTC channel 0 one-shot compare event
|
||||
* \param channel AON_RTC_CH0 or AON_RTC_CH1
|
||||
* \param t The time when the event will be fired. This is an absolute
|
||||
* time, in other words the event will fire AT time \e t,
|
||||
* not IN \e t ticks
|
||||
*
|
||||
* Channel AON_RTC_CH0 is reserved for the rtimer. AON_RTC_CH1 is reserved
|
||||
* for the system clock.
|
||||
*
|
||||
* User applications should not use this function. User applications should
|
||||
* instead use Contiki's timer-related libraries
|
||||
*/
|
||||
void cc26xx_rtc_schedule_one_shot(uint32_t t);
|
||||
void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t t);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC26XX_RTC_H_ */
|
||||
#endif /* SOC_RTC_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
|
@ -34,7 +34,7 @@
|
|||
* @{
|
||||
*
|
||||
* \file
|
||||
* Driver for the CC26xx IEEE addresses
|
||||
* Driver for the CC13xx/CC26xx IEEE addresses
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
|
@ -33,7 +33,7 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-ieee-addr CC26xx IEEE Address Control
|
||||
* \defgroup cc26xx-ieee-addr CC13xx/CC26xx IEEE Address Control
|
||||
*
|
||||
* Driver for the retrieval of an IEEE address from flash
|
||||
*
|
1
cpu/cc26xx-cc13xx/lib/cc13xxware
Submodule
1
cpu/cc26xx-cc13xx/lib/cc13xxware
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 63ed52888467ea7d403b0c743852162395232c9e
|
1
cpu/cc26xx-cc13xx/lib/cc26xxware
Submodule
1
cpu/cc26xx-cc13xx/lib/cc26xxware
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 0e82b18bf2c69fb0a40af4d2496db2a3dc721cec
|
|
@ -32,12 +32,12 @@
|
|||
* \addtogroup cc26xx-lpm
|
||||
* @{
|
||||
*
|
||||
* Implementation of CC26xx low-power operation functionality
|
||||
* Implementation of CC13xx/CC26xx low-power operation functionality
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Driver for CC26xx's low-power operation
|
||||
* Driver for CC13xx/CC26xx low-power operation
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "prcm.h"
|
||||
|
@ -48,8 +48,11 @@
|
|||
#include "lib/list.h"
|
||||
#include "dev/leds.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "dev/cc26xx-rtc.h"
|
||||
#include "dev/soc-rtc.h"
|
||||
#include "dev/oscillators.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if ENERGEST_CONF_ON
|
||||
static unsigned long irq_energest = 0;
|
||||
|
@ -72,7 +75,10 @@ LIST(modules_list);
|
|||
* Don't consider standby mode if the next AON RTC event is scheduled to fire
|
||||
* in less than STANDBY_MIN_DURATION rtimer ticks
|
||||
*/
|
||||
#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 8)
|
||||
#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 11)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Prototype of a function in clock.c. Called every time we come out of DS */
|
||||
void clock_update(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
|
||||
|
@ -93,10 +99,10 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
|
|||
|
||||
/* Reset AON even fabric to default wakeup sources */
|
||||
for(i = AON_EVENT_MCU_WU0; i <= AON_EVENT_MCU_WU3; i++) {
|
||||
ti_lib_aon_event_mcu_wake_up_set(i, AON_EVENT_NULL);
|
||||
ti_lib_aon_event_mcu_wake_up_set(i, AON_EVENT_NONE);
|
||||
}
|
||||
for(i = AON_EVENT_AUX_WU0; i <= AON_EVENT_AUX_WU2; i++) {
|
||||
ti_lib_aon_event_aux_wake_up_set(i, AON_EVENT_NULL);
|
||||
ti_lib_aon_event_aux_wake_up_set(i, AON_EVENT_NONE);
|
||||
}
|
||||
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
@ -222,6 +228,14 @@ wake_up(void)
|
|||
/* Check operating conditions, optimally choose DCDC versus GLDO */
|
||||
ti_lib_sys_ctrl_dcdc_voltage_conditional_control();
|
||||
|
||||
/*
|
||||
* We may or may not have been woken up by an AON RTC tick. If not, we need
|
||||
* to adjust our software tick counter
|
||||
*/
|
||||
clock_update();
|
||||
|
||||
watchdog_periodic();
|
||||
|
||||
/* Notify all registered modules that we've just woken up */
|
||||
for(module = list_head(modules_list); module != NULL;
|
||||
module = module->next) {
|
||||
|
@ -237,10 +251,11 @@ lpm_drop()
|
|||
lpm_registered_module_t *module;
|
||||
uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
|
||||
uint8_t module_pm;
|
||||
clock_time_t next_event;
|
||||
|
||||
uint32_t domains = LOCKABLE_DOMAINS;
|
||||
|
||||
if(RTIMER_CLOCK_LT(cc26xx_rtc_get_next_trigger(),
|
||||
if(RTIMER_CLOCK_LT(soc_rtc_get_next_trigger(),
|
||||
RTIMER_NOW() + STANDBY_MIN_DURATION)) {
|
||||
lpm_sleep();
|
||||
return;
|
||||
|
@ -269,6 +284,18 @@ lpm_drop()
|
|||
/* Critical. Don't get interrupted! */
|
||||
ti_lib_int_master_disable();
|
||||
|
||||
/*
|
||||
* Reschedule AON RTC CH1 to fire an event N ticks before the next etimer
|
||||
* event
|
||||
*/
|
||||
next_event = etimer_next_expiration_time();
|
||||
|
||||
if(next_event) {
|
||||
next_event = next_event - clock_time();
|
||||
soc_rtc_schedule_one_shot(AON_RTC_CH1, RTIMER_NOW() +
|
||||
(next_event * (RTIMER_SECOND / CLOCK_SECOND)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify all registered modules that we are dropping to mode X. We do not
|
||||
* need to do this for simple sleep.
|
||||
|
@ -357,7 +384,7 @@ lpm_drop()
|
|||
while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON);
|
||||
|
||||
/* Configure the recharge controller */
|
||||
ti_lib_sys_ctrl_set_recharge_before_power_down(false);
|
||||
ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE);
|
||||
|
||||
/*
|
||||
* If both PERIPH and SERIAL PDs are off, request the uLDO as the power
|
||||
|
@ -436,6 +463,9 @@ void
|
|||
lpm_init()
|
||||
{
|
||||
list_init(modules_list);
|
||||
|
||||
/* Always wake up on any DIO edge detection */
|
||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU2, AON_EVENT_IO);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
|
@ -32,14 +32,14 @@
|
|||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-lpm CC26xx Low-Power management
|
||||
* \defgroup cc26xx-lpm CC13xx/CC26xx Low-Power management
|
||||
*
|
||||
* CC26xx low-power operation
|
||||
* CC13xx/CC26xx low-power operation
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the management of CC26xx low-power operation
|
||||
* Header file for the management of CC13xx/CC26xx low-power operation
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef LPM_H_
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue