40 #include "ctk/ctk-textentry-cmdline.h"
41 #include "contiki-net.h"
45 #if WWW_CONF_WITH_WGET
46 #include "program-handler.h"
49 #include "webclient.h"
50 #include "htmlparser.h"
51 #include "http-strings.h"
56 char *itoa(
int value,
char *str,
int base);
59 static char url[WWW_CONF_MAX_URLLEN + 1];
62 static char webpage[WWW_CONF_WEBPAGE_WIDTH *
63 WWW_CONF_WEBPAGE_HEIGHT + 1];
68 #if WWW_CONF_HISTORY_SIZE > 0
69 static struct ctk_button backbutton =
71 static struct ctk_button downbutton =
74 static struct ctk_button downbutton =
77 static struct ctk_button stopbutton =
78 {
CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 16, 0, 4,
"Stop")};
79 static struct ctk_button gobutton =
80 {
CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 4, 0, 2,
"Go")};
82 static struct ctk_separator sep1 =
85 static char editurl[WWW_CONF_MAX_URLLEN + 1];
86 static struct ctk_textentry urlentry =
88 1, editurl, WWW_CONF_MAX_URLLEN)};
89 static struct ctk_label webpagelabel =
91 WWW_CONF_WEBPAGE_HEIGHT, webpage)};
93 static char statustexturl[WWW_CONF_WEBPAGE_WIDTH];
94 static struct ctk_label statustext =
95 {
CTK_LABEL(0, WWW_CONF_WEBPAGE_HEIGHT + 4,
96 WWW_CONF_WEBPAGE_WIDTH, 1,
"")};
97 static struct ctk_separator sep2 =
99 WWW_CONF_WEBPAGE_WIDTH)};
101 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
104 static struct ctk_label wgetlabel1 =
105 {
CTK_LABEL(1, 1, 34, 1,
"This web page cannot be displayed.")};
106 static struct ctk_label wgetlabel2 =
107 {
CTK_LABEL(1, 3, 35, 1,
"Would you like to download instead?")};
108 static struct ctk_button wgetnobutton =
110 static struct ctk_button wgetyesbutton =
111 {
CTK_BUTTON(11, 5, 24,
"Close browser & download")};
113 static struct ctk_button wgetnobutton =
114 {
CTK_BUTTON((WWW_CONF_WEBPAGE_WIDTH - 38) / 2 + 1,
116 static struct ctk_button wgetyesbutton =
117 {
CTK_BUTTON((WWW_CONF_WEBPAGE_WIDTH - 38) / 2 + 11,
118 11, 24,
"Close browser & download")};
122 #if WWW_CONF_HISTORY_SIZE > 0
124 static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];
125 static unsigned char history_last;
129 struct ctk_hyperlink hyperlink;
136 struct inputattrib *nextptr;
141 struct inputattrib *nextptr;
142 struct formattrib *formptr;
147 struct inputattrib *nextptr;
148 struct formattrib *formptr;
149 struct ctk_textentry textentry;
153 struct submitattrib {
154 struct inputattrib *nextptr;
155 struct formattrib *formptr;
156 struct ctk_button button;
160 static char pageattribs[WWW_CONF_PAGEATTRIB_SIZE];
161 static char *pageattribptr;
164 static struct formattrib *formptr;
165 static struct inputattrib *currptr;
169 #define ISO_space 0x20
170 #define ISO_hash 0x23
171 #define ISO_ampersand 0x26
172 #define ISO_plus 0x2b
173 #define ISO_slash 0x2f
175 #define ISO_questionmark 0x3f
178 static char *webpageptr;
179 static unsigned char x, y;
180 static unsigned char loading;
181 static unsigned short firsty, pagey;
182 static unsigned char newlines;
184 static unsigned char count;
185 static char receivingmsgs[4][23] = {
186 "Receiving web page ...",
187 "Receiving web page. ..",
188 "Receiving web page.. .",
189 "Receiving web page... "
192 PROCESS(www_process,
"Web browser");
194 AUTOSTART_PROCESSES(&www_process);
196 static void formsubmit(
struct inputattrib *trigger);
206 #if WWW_CONF_HISTORY_SIZE > 0
215 CTK_WIDGET_SET_FLAG(&webpagelabel, CTK_WIDGET_FLAG_MONOSPACE);
219 pageattribptr = pageattribs;
233 add_pageattrib(
unsigned size)
237 if(pageattribptr + size > pageattribs +
sizeof(pageattribs)) {
241 pageattribptr += size;
247 add_forminput(
struct inputattrib *inputptr)
249 inputptr->nextptr =
NULL;
250 currptr->nextptr = inputptr;
260 memset(webpage, 0, WWW_CONF_WEBPAGE_WIDTH * WWW_CONF_WEBPAGE_HEIGHT);
267 memcpy(editurl, url, WWW_CONF_MAX_URLLEN);
268 strncpy(editurl,
"http://", 7);
269 petsciiconv_topetscii(editurl + 7, WWW_CONF_MAX_URLLEN - 7);
280 webpageptr = webpage;
286 show_statustext(
char *text)
293 end_page(
char *status,
void *focus)
295 show_statustext(status);
296 petsciiconv_topetscii(webpageptr - x, x);
299 log_message(
"Page attribs free: ", itoa(pageattribs +
sizeof(pageattribs) - pageattribptr,
300 pageattribs +
sizeof(pageattribs) - 5, 10));
313 static char host[32];
315 register char *urlptr;
316 static uip_ipaddr_t
addr;
319 urlptr = url + strlen(url);
320 while(urlptr > url) {
321 if(*(urlptr - 1) ==
' ') {
334 if(strncmp(url, http_http, 7) != 0) {
335 while(urlptr >= url) {
336 *(urlptr + 7) = *urlptr;
339 strncpy(url, http_http, 7);
344 for(i = 0; i <
sizeof(host); ++i) {
361 while(*urlptr !=
'/' && *urlptr != 0) {
374 uip_ipaddr_t *addrptr;
377 show_statustext(
"Resolving host...");
388 if(webclient_get(host, 80, file) == 0) {
389 show_statustext(
"Out of memory error");
391 show_statustext(
"Connecting...");
403 register char *urlptr;
405 if(strncmp(link, http_http, 7) == 0) {
408 strncpy(url, link, WWW_CONF_MAX_URLLEN);
409 }
else if(*link == ISO_slash &&
410 *(link + 1) == ISO_slash) {
415 strncpy(&url[5], link, WWW_CONF_MAX_URLLEN);
416 }
else if(*link == ISO_slash) {
421 for(urlptr = &url[7];
422 *urlptr != 0 && *urlptr != ISO_slash;
424 strncpy(urlptr, link, WWW_CONF_MAX_URLLEN - (urlptr - url));
430 for(urlptr = url + strlen(url);
431 urlptr != url && *urlptr != ISO_slash;
434 strncpy(urlptr, link, WWW_CONF_MAX_URLLEN - (urlptr - url));
438 #if WWW_CONF_HISTORY_SIZE > 0
447 if(strncmp(url, history[(
int)history_last], WWW_CONF_MAX_URLLEN) != 0) {
448 memcpy(history[(
int)history_last], url, WWW_CONF_MAX_URLLEN);
450 if(history_last >= WWW_CONF_HISTORY_SIZE) {
472 #if WWW_CONF_WITH_WGET
481 memset(webpage, 0,
sizeof(webpage));
483 WWW_CONF_WEBPAGE_HEIGHT+5,
"Web browser");
485 #ifdef WWW_CONF_HOMEPAGE
486 strncpy(editurl, WWW_CONF_HOMEPAGE,
sizeof(editurl));
490 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
493 ctk_dialog_new(&wgetdialog, 38, 7);
508 webclient_appcall(data);
514 #if WWW_CONF_HISTORY_SIZE > 0
517 memcpy(url, editurl, WWW_CONF_MAX_URLLEN);
518 petsciiconv_toascii(url, WWW_CONF_MAX_URLLEN);
521 #if WWW_CONF_HISTORY_SIZE > 0
522 }
else if(w == (
struct ctk_widget *)&backbutton) {
527 if(history_last > WWW_CONF_HISTORY_SIZE) {
528 history_last = WWW_CONF_HISTORY_SIZE - 1;
530 memcpy(url, history[(
int)history_last], WWW_CONF_MAX_URLLEN);
531 *history[(int)history_last] = 0;
535 }
else if(w == (
struct ctk_widget *)&downbutton) {
536 firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 2;
540 }
else if(w == (
struct ctk_widget *)&stopbutton) {
543 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
544 }
else if(w == (
struct ctk_widget *)&wgetnobutton) {
550 }
else if(w == (
struct ctk_widget *)&wgetyesbutton) {
556 #if WWW_CONF_WITH_WGET
558 argptr =
arg_alloc((
char)WWW_CONF_MAX_URLLEN);
560 strncpy(argptr, url, WWW_CONF_MAX_URLLEN);
564 petsciiconv_topetscii(url,
sizeof(url));
567 WWW_CONF_WGET_EXEC(url);
569 show_statustext(
"Cannot exec wget");
575 formsubmit((
struct inputattrib *)
576 (((
char *)w) - offsetof(
struct inputattrib,
widget)));
581 #if WWW_CONF_HISTORY_SIZE > 0
584 set_link(w->
widget.hyperlink.url);
591 strncpy(statustexturl, w->
widget.hyperlink.url,
592 sizeof(statustexturl));
593 petsciiconv_topetscii(statustexturl,
sizeof(statustexturl));
594 show_statustext(statustexturl);
599 if((
char *)data !=
NULL &&
603 show_statustext(
"Host not found");
607 ev == PROCESS_EVENT_EXIT) {
621 set_url(
char *host, uint16_t port,
char *file)
625 memset(url, 0, WWW_CONF_MAX_URLLEN);
627 if(strncmp(file, http_http, 7) == 0) {
628 strncpy(url, file,
sizeof(url));
630 strncpy(url, http_http, 7);
632 strcpy(urlptr, host);
633 urlptr += strlen(host);
634 strcpy(urlptr, file);
646 webclient_aborted(
void)
648 show_statustext(
"Connection reset by peer");
657 webclient_timedout(
void)
659 show_statustext(
"Connection timed out");
669 webclient_closed(
void)
671 end_page(
"Stopped", &downbutton);
680 webclient_connected(
void)
684 show_statustext(
"Request sent...");
685 set_url(webclient_hostname(), webclient_port(), webclient_filename());
696 webclient_datahandler(
char *data, uint16_t len)
699 if(strstr(webclient_mimetype(), http_html + 1) != 0) {
700 count = (count + 1) & 3;
701 show_statustext(receivingmsgs[count]);
702 htmlparser_parse(data, len);
706 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
708 ctk_dialog_open(&wgetdialog);
710 strcpy(webpage + WWW_CONF_WEBPAGE_WIDTH * 5,
711 (80 - WWW_CONF_WEBPAGE_WIDTH) / 2 +
712 " This web page cannot be displayed.");
713 strcpy(webpage + WWW_CONF_WEBPAGE_WIDTH * 6,
714 (80 - WWW_CONF_WEBPAGE_WIDTH) / 2 +
715 " Would you like to download instead?");
730 end_page(
"Done", &urlentry);
735 add_pagewidget(
char *text,
unsigned char size,
char *attrib,
unsigned char type,
736 unsigned char border)
739 static unsigned char maxwidth;
747 maxwidth = size ? WWW_CONF_WEBPAGE_WIDTH - (1 + 2 * border)
748 : WWW_CONF_WEBPAGE_WIDTH;
753 if(size + x > maxwidth) {
754 htmlparser_newline();
764 if(size > maxwidth) {
769 if(firsty == pagey) {
770 unsigned char attriblen = strlen(attrib);
777 memcpy(wptr, text, size);
779 wptr[size + border] =
' ';
783 struct linkattrib *linkptr =
784 (
struct linkattrib *)add_pageattrib(
sizeof(
struct linkattrib) + attriblen);
785 if(linkptr !=
NULL) {
786 CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url);
787 strcpy(linkptr->url, attrib);
788 CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE);
795 struct submitattrib *submitptr =
796 (
struct submitattrib *)add_pageattrib(
sizeof(
struct submitattrib) + attriblen);
797 if(submitptr !=
NULL) {
798 CTK_BUTTON_NEW((
struct ctk_button *)&submitptr->button, x, y + 3, size, wptr);
799 add_forminput((
struct inputattrib *)submitptr);
800 submitptr->formptr = formptr;
801 strcpy(submitptr->name, attrib);
802 CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE);
808 struct textattrib *textptr =
809 (
struct textattrib *)add_pageattrib(
sizeof(
struct textattrib) + attriblen
810 + (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1);
811 if(textptr !=
NULL) {
812 CTK_TEXTENTRY_NEW((
struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1,
813 textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
814 add_forminput((
struct inputattrib *)textptr);
815 textptr->formptr = formptr;
816 petsciiconv_topetscii(text, strlen(text));
817 strcpy(textptr->textentry.text, text);
818 strcpy(textptr->name, attrib);
820 CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE);
832 size += 1 + 2 * border;
836 if(firsty == pagey) {
840 if(x == WWW_CONF_WEBPAGE_WIDTH) {
841 htmlparser_newline();
846 htmlparser_newline(
void)
866 webpageptr += (WWW_CONF_WEBPAGE_WIDTH - x);
871 wptr = webpageptr - WWW_CONF_WEBPAGE_WIDTH;
872 petsciiconv_topetscii(wptr, WWW_CONF_WEBPAGE_WIDTH);
875 if(y == WWW_CONF_WEBPAGE_HEIGHT) {
882 htmlparser_word(
char *word,
unsigned char wordlen)
887 if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
888 htmlparser_newline();
892 if(pagey == firsty) {
893 memcpy(webpageptr, word, wordlen);
894 webpageptr += wordlen;
899 if(x == WWW_CONF_WEBPAGE_WIDTH) {
900 htmlparser_newline();
907 htmlparser_link(
char *text,
unsigned char textlen,
char *url)
910 if(url[0] == ISO_hash || strncmp(url, http_https,
sizeof(http_https) - 1) == 0) {
911 htmlparser_word(text, textlen);
919 htmlparser_form(
char *action)
921 formptr = (
struct formattrib *)add_pageattrib(
sizeof(
struct formattrib) + strlen(action));
922 if(formptr !=
NULL) {
923 formptr->nextptr =
NULL;
924 currptr = (
struct inputattrib *)formptr;
925 strcpy(formptr->action, action);
930 htmlparser_submitbutton(
char *text,
char *name)
936 htmlparser_inputfield(
unsigned char type,
unsigned char size,
char *text,
char *name)
938 if(type == HTMLPARSER_INPUTTYPE_HIDDEN) {
946 add_query(
char delimiter,
char *
string)
949 unsigned char length;
951 if(delimiter == ISO_questionmark) {
952 query = url + strlen(url);
955 length = strlen(
string);
956 if(query - url + WWW_CONF_MAX_URLLEN - 1 < length) {
960 *query++ = delimiter;
961 strcpy(query,
string);
962 if(delimiter == ISO_eq) {
965 petsciiconv_toascii(query, length);
966 while((space = strchr(space, ISO_space)) !=
NULL) {
974 formsubmit(
struct inputattrib *trigger)
976 struct inputattrib *
input;
977 struct formattrib *form = trigger->formptr;
978 char delimiter = ISO_questionmark;
980 set_link(form->action);
987 for(input = form->nextptr; input !=
NULL; input = input->nextptr) {
992 name = ((
struct textattrib *)input)->name;
993 value = ((
struct textattrib *)input)->textentry.text;
996 if(trigger ==
NULL) {
999 if(input != trigger) {
1002 name = ((
struct submitattrib *)input)->name;
1003 value = ((
struct submitattrib *)input)->button.text;
1006 add_query(delimiter, name);
1007 add_query(ISO_eq, value);
1008 delimiter = ISO_ampersand;
1011 #if WWW_CONF_HISTORY_SIZE > 0
process_event_t ctk_signal_hyperlink_hover
Same as ctk_signal_widget_select.
char * arg_alloc(char size)
Allocates an argument buffer.
#define uip_abort()
Abort the current connection.
void ctk_window_close(struct ctk_window *w)
Close a window if it is open.
static uip_ds6_addr_t * addr
Pointer to a router list entry.
process_event_t tcpip_event
The uIP event.
#define CTK_WIDGET_ADD(win, widg)
Add a widget to a window.
#define CTK_BUTTON(x, y, w, text)
Instantiating macro for the ctk_button widget.
void ctk_window_new(struct ctk_window *window, unsigned char w, unsigned char h, char *title)
Create a new window.
process_event_t ctk_signal_widget_activate
Emitted when a widget is activated (pressed).
PETSCII/ASCII conversion functions.
#define PROCESS_END()
Define the end of a process.
#define PROCESS(name, strname)
Declare a process.
process_event_t ctk_signal_hyperlink_activate
Emitted when a hyperlink is activated.
static void input(void)
Process a received 6lowpan packet.
process_event_t ctk_signal_window_close
Emitted when a window is closed.
#define CTK_SEPARATOR(x, y, w)
Instantiating macro for the ctk_separator widget.
unsigned char type
The type of the widget: CTK_WIDGET_SEPARATOR, CTK_WIDGET_LABEL, CTK_WIDGET_BUTTON, CTK_WIDGET_HYPERLINK, CTK_WIDGET_TEXTENTRY, CTK_WIDGET_BITMAP or CTK_WIDGET_ICON.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
void process_exit(struct process *p)
Cause a process to exit.
union ctk_widget::@34 widget
The union which contains the actual widget structure, as determined by the type field.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Representation of a CTK window.
process_event_t resolv_event_found
Event that is broadcasted when a DNS name has been resolved.
#define CTK_WIDGET_TYPE(w)
Obtain the type of a widget.
#define ctk_label_set_text(l, t)
Set the text of a label.
#define CTK_LABEL(x, y, w, h, text)
Instantiating macro for the ctk_label widget.
#define LOADER_UNLOAD()
Unload a program from memory.
#define CTK_TEXTENTRY(x, y, w, h, text, len)
Instantiating macro for the ctk_textentry widget.
void program_handler_load(char *name, char *arg)
Loads a program and displays a dialog telling the user about it.
#define NULL
The null pointer.
void ctk_window_clear(struct ctk_window *w)
Remove all widgets from a window.
resolv_status_t resolv_lookup(const char *name, uip_ipaddr_t **ipaddr)
Look up a hostname in the array of known hostnames.
#define CTK_WIDGET_FOCUS(win, widg)
Set focus to a widget.
#define CTK_WIDGET_BUTTON
Widget number: The CTK button widget.
Hostname is fresh and usable.
static volatile clock_time_t count
These routines define the AVR-specific calls declared in /core/sys/clock.h CLOCK_SECOND is the number...
#define CTK_WIDGET_HYPERLINK
Widget number: The CTK hyperlink widget.
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
void resolv_query(const char *name)
Queues a name so that a question for the name will be sent out.
void ctk_window_redraw(struct ctk_window *w)
Redraw a window.
void ctk_window_open(CC_REGISTER_ARG struct ctk_window *w)
Open a window, or bring window to front if already open.
unsigned char w
The width of the widget in character coordinates.
#define CTK_WIDGET_TEXTENTRY
Widget number: The CTK textentry widget.
The generic CTK widget structure that contains all other widget structures.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define CTK_WIDGET_REDRAW(widg)
Add a widget to the redraw queue.
#define PROCESS_BEGIN()
Define the beginning of a process.