00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00095
00096
00097
00098
00099
00100 #define MY_MAC "\x00\x06\x98\x30\x00\x35"
00101
00102
00103
00104
00105
00106
00107 #define MY_IPADDR "192.168.192.35"
00108
00109
00110
00111
00112
00113
00114 #define MY_IPMASK "255.255.255.0"
00115
00116
00117
00118
00119
00120
00121 #define MY_IPGATE "192.168.192.1"
00122
00123
00124 #if !defined(__IMAGECRAFT__)
00125
00126
00127 #define USE_DHCP
00128
00129 #define USE_DISCOVERY
00130
00131
00132
00133 #endif
00134
00135
00136 #ifdef USE_PHAT
00137
00138 #if defined(ETHERNUT3)
00139
00140
00141 #define MY_FSDEV devPhat0
00142 #define MY_FSDEV_NAME "PHAT0"
00143
00144
00145 #define MY_BLKDEV devNplMmc0
00146 #define MY_BLKDEV_NAME "MMC0"
00147
00148 #elif defined(AT91SAM7X_EK)
00149
00150
00151 #define MY_FSDEV devPhat0
00152 #define MY_FSDEV_NAME "PHAT0"
00153
00154
00155 #define MY_BLKDEV devAt91SpiMmc0
00156 #define MY_BLKDEV_NAME "MMC0"
00157
00158 #elif defined(AT91SAM9260_EK)
00159
00160
00161 #define MY_FSDEV devPhat0
00162 #define MY_FSDEV_NAME "PHAT0"
00163
00164
00165 #define MY_BLKDEV devAt91Mci0
00166 #define MY_BLKDEV_NAME "MCI0"
00167
00168 #endif
00169 #endif
00170
00171 #ifndef MY_FSDEV
00172 #define MY_FSDEV devUrom
00173 #endif
00174
00175 #ifdef MY_FSDEV_NAME
00176 #define MY_HTTPROOT MY_FSDEV_NAME ":/"
00177 #endif
00178
00179
00180 #include <cfg/os.h>
00181
00182 #include <string.h>
00183 #include <io.h>
00184 #include <fcntl.h>
00185
00186 #include <dev/board.h>
00187 #include <dev/urom.h>
00188 #include <dev/nplmmc.h>
00189 #include <dev/sbimmc.h>
00190 #include <fs/phatfs.h>
00191
00192 #include <sys/version.h>
00193 #include <sys/thread.h>
00194 #include <sys/timer.h>
00195 #include <sys/heap.h>
00196 #include <sys/confnet.h>
00197 #include <sys/socket.h>
00198
00199 #include <arpa/inet.h>
00200 #include <net/route.h>
00201
00202 #include <pro/httpd.h>
00203 #include <pro/dhcp.h>
00204 #include <pro/ssi.h>
00205 #include <pro/asp.h>
00206 #include <pro/discover.h>
00207
00208 #ifdef NUTDEBUG
00209 #include <sys/osdebug.h>
00210 #include <net/netdebug.h>
00211 #endif
00212
00213 static char *html_mt = "text/html";
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 static int ASPCallback (char *pASPFunction, FILE *stream)
00229 {
00230 if (strcmp(pASPFunction, "usr_date") == 0) {
00231 fprintf(stream, "Dummy example: 01.01.2005");
00232 return(0);
00233 }
00234
00235 if (strcmp(pASPFunction, "usr_time") == 0) {
00236 fprintf(stream, "Dummy example: 12:15:02");
00237 return(0);
00238 }
00239
00240 return (-1);
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 static int ShowQuery(FILE * stream, REQUEST * req)
00253 {
00254 char *cp;
00255
00256
00257
00258
00259
00260
00261 static prog_char head[] = "<HTML><HEAD><TITLE>Parameters</TITLE></HEAD><BODY><H1>Parameters</H1>";
00262 static prog_char foot[] = "</BODY></HTML>";
00263 static prog_char req_fmt[] = "Method: %s<BR>\r\nVersion: HTTP/%d.%d<BR>\r\nContent length: %d<BR>\r\n";
00264 static prog_char url_fmt[] = "URL: %s<BR>\r\n";
00265 static prog_char query_fmt[] = "Argument: %s<BR>\r\n";
00266 static prog_char type_fmt[] = "Content type: %s<BR>\r\n";
00267 static prog_char cookie_fmt[] = "Cookie: %s<BR>\r\n";
00268 static prog_char auth_fmt[] = "Auth info: %s<BR>\r\n";
00269 static prog_char agent_fmt[] = "User agent: %s<BR>\r\n";
00270
00271
00272 NutHttpSendHeaderTop(stream, req, 200, "Ok");
00273 NutHttpSendHeaderBot(stream, html_mt, -1);
00274
00275
00276 fputs_P(head, stream);
00277
00278
00279
00280
00281 switch (req->req_method) {
00282 case METHOD_GET:
00283 cp = "GET";
00284 break;
00285 case METHOD_POST:
00286 cp = "POST";
00287 break;
00288 case METHOD_HEAD:
00289 cp = "HEAD";
00290 break;
00291 default:
00292 cp = "UNKNOWN";
00293 break;
00294 }
00295 fprintf_P(stream, req_fmt, cp, req->req_version / 10, req->req_version % 10, req->req_length);
00296 if (req->req_url)
00297 fprintf_P(stream, url_fmt, req->req_url);
00298 if (req->req_query)
00299 fprintf_P(stream, query_fmt, req->req_query);
00300 if (req->req_type)
00301 fprintf_P(stream, type_fmt, req->req_type);
00302 if (req->req_cookie)
00303 fprintf_P(stream, cookie_fmt, req->req_cookie);
00304 if (req->req_auth)
00305 fprintf_P(stream, auth_fmt, req->req_auth);
00306 if (req->req_agent)
00307 fprintf_P(stream, agent_fmt, req->req_agent);
00308
00309
00310 fputs_P(foot, stream);
00311 fflush(stream);
00312
00313 return 0;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 static int ShowThreads(FILE * stream, REQUEST * req)
00324 {
00325 static prog_char head[] = "<HTML><HEAD><TITLE>Threads</TITLE></HEAD><BODY><H1>Threads</H1>\r\n"
00326 "<TABLE BORDER><TR><TH>Handle</TH><TH>Name</TH><TH>Priority</TH><TH>Status</TH><TH>Event<BR>Queue</TH><TH>Timer</TH><TH>Stack-<BR>pointer</TH><TH>Free<BR>Stack</TH></TR>\r\n";
00327 #if defined(__AVR__)
00328 static prog_char tfmt[] =
00329 "<TR><TD>%04X</TD><TD>%s</TD><TD>%u</TD><TD>%s</TD><TD>%04X</TD><TD>%04X</TD><TD>%04X</TD><TD>%u</TD><TD>%s</TD></TR>\r\n";
00330 #else
00331 static prog_char tfmt[] =
00332 "<TR><TD>%08lX</TD><TD>%s</TD><TD>%u</TD><TD>%s</TD><TD>%08lX</TD><TD>%08lX</TD><TD>%08lX</TD><TD>%lu</TD><TD>%s</TD></TR>\r\n";
00333 #endif
00334 static prog_char foot[] = "</TABLE></BODY></HTML>";
00335 static char *thread_states[] = { "TRM", "<FONT COLOR=#CC0000>RUN</FONT>", "<FONT COLOR=#339966>RDY</FONT>", "SLP" };
00336 NUTTHREADINFO *tdp = nutThreadList;
00337
00338
00339 NutHttpSendHeaderTop(stream, req, 200, "Ok");
00340 NutHttpSendHeaderBot(stream, html_mt, -1);
00341
00342
00343 fputs_P(head, stream);
00344 for (tdp = nutThreadList; tdp; tdp = tdp->td_next) {
00345 fprintf_P(stream, tfmt, (uptr_t) tdp, tdp->td_name, tdp->td_priority,
00346 thread_states[tdp->td_state], (uptr_t) tdp->td_queue, (uptr_t) tdp->td_timer,
00347 (uptr_t) tdp->td_sp, (uptr_t) tdp->td_sp - (uptr_t) tdp->td_memory,
00348 *((u_long *) tdp->td_memory) != DEADBEEF ? "Corr" : "OK");
00349 }
00350 fputs_P(foot, stream);
00351 fflush(stream);
00352
00353 return 0;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363 static int ShowTimers(FILE * stream, REQUEST * req)
00364 {
00365 static prog_char head[] = "<HTML><HEAD><TITLE>Timers</TITLE></HEAD><BODY><H1>Timers</H1>\r\n";
00366 static prog_char thead[] =
00367 "<TABLE BORDER><TR><TH>Handle</TH><TH>Countdown</TH><TH>Tick Reload</TH><TH>Callback<BR>Address</TH><TH>Callback<BR>Argument</TH></TR>\r\n";
00368 #if defined(__AVR__)
00369 static prog_char tfmt[] = "<TR><TD>%04X</TD><TD>%lu</TD><TD>%lu</TD><TD>%04X</TD><TD>%04X</TD></TR>\r\n";
00370 #else
00371 static prog_char tfmt[] = "<TR><TD>%08lX</TD><TD>%lu</TD><TD>%lu</TD><TD>%08lX</TD><TD>%08lX</TD></TR>\r\n";
00372 #endif
00373 static prog_char foot[] = "</TABLE></BODY></HTML>";
00374 NUTTIMERINFO *tnp;
00375 u_long ticks_left;
00376
00377 NutHttpSendHeaderTop(stream, req, 200, "Ok");
00378 NutHttpSendHeaderBot(stream, html_mt, -1);
00379
00380
00381 fputs_P(head, stream);
00382 if ((tnp = nutTimerList) != 0) {
00383 fputs_P(thead, stream);
00384 ticks_left = 0;
00385 while (tnp) {
00386 ticks_left += tnp->tn_ticks_left;
00387 fprintf_P(stream, tfmt, (uptr_t) tnp, ticks_left, tnp->tn_ticks, (uptr_t) tnp->tn_callback, (uptr_t) tnp->tn_arg);
00388 tnp = tnp->tn_next;
00389 }
00390 }
00391
00392 fputs_P(foot, stream);
00393 fflush(stream);
00394
00395 return 0;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 static int ShowSockets(FILE * stream, REQUEST * req)
00406 {
00407
00408 static prog_char head[] = "<HTML><HEAD><TITLE>Sockets</TITLE></HEAD>"
00409 "<BODY><H1>Sockets</H1>\r\n"
00410 "<TABLE BORDER><TR><TH>Handle</TH><TH>Type</TH><TH>Local</TH><TH>Remote</TH><TH>Status</TH></TR>\r\n";
00411 #if defined(__AVR__)
00412 static prog_char tfmt1[] = "<TR><TD>%04X</TD><TD>TCP</TD><TD>%s:%u</TD>";
00413 #else
00414 static prog_char tfmt1[] = "<TR><TD>%08lX</TD><TD>TCP</TD><TD>%s:%u</TD>";
00415 #endif
00416 static prog_char tfmt2[] = "<TD>%s:%u</TD><TD>";
00417 static prog_char foot[] = "</TABLE></BODY></HTML>";
00418 static prog_char st_listen[] = "LISTEN";
00419 static prog_char st_synsent[] = "SYNSENT";
00420 static prog_char st_synrcvd[] = "SYNRCVD";
00421 static prog_char st_estab[] = "<FONT COLOR=#CC0000>ESTABL</FONT>";
00422 static prog_char st_finwait1[] = "FINWAIT1";
00423 static prog_char st_finwait2[] = "FINWAIT2";
00424 static prog_char st_closewait[] = "CLOSEWAIT";
00425 static prog_char st_closing[] = "CLOSING";
00426 static prog_char st_lastack[] = "LASTACK";
00427 static prog_char st_timewait[] = "TIMEWAIT";
00428 static prog_char st_closed[] = "CLOSED";
00429 static prog_char st_unknown[] = "UNKNOWN";
00430 prog_char *st_P;
00431 extern TCPSOCKET *tcpSocketList;
00432 TCPSOCKET *ts;
00433
00434 NutHttpSendHeaderTop(stream, req, 200, "Ok");
00435 NutHttpSendHeaderBot(stream, html_mt, -1);
00436
00437
00438 fputs_P(head, stream);
00439 for (ts = tcpSocketList; ts; ts = ts->so_next) {
00440 switch (ts->so_state) {
00441 case TCPS_LISTEN:
00442 st_P = (prog_char *) st_listen;
00443 break;
00444 case TCPS_SYN_SENT:
00445 st_P = (prog_char *) st_synsent;
00446 break;
00447 case TCPS_SYN_RECEIVED:
00448 st_P = (prog_char *) st_synrcvd;
00449 break;
00450 case TCPS_ESTABLISHED:
00451 st_P = (prog_char *) st_estab;
00452 break;
00453 case TCPS_FIN_WAIT_1:
00454 st_P = (prog_char *) st_finwait1;
00455 break;
00456 case TCPS_FIN_WAIT_2:
00457 st_P = (prog_char *) st_finwait2;
00458 break;
00459 case TCPS_CLOSE_WAIT:
00460 st_P = (prog_char *) st_closewait;
00461 break;
00462 case TCPS_CLOSING:
00463 st_P = (prog_char *) st_closing;
00464 break;
00465 case TCPS_LAST_ACK:
00466 st_P = (prog_char *) st_lastack;
00467 break;
00468 case TCPS_TIME_WAIT:
00469 st_P = (prog_char *) st_timewait;
00470 break;
00471 case TCPS_CLOSED:
00472 st_P = (prog_char *) st_closed;
00473 break;
00474 default:
00475 st_P = (prog_char *) st_unknown;
00476 break;
00477 }
00478
00479
00480
00481 fprintf_P(stream, tfmt1, (uptr_t) ts, inet_ntoa(ts->so_local_addr), ntohs(ts->so_local_port));
00482 fprintf_P(stream, tfmt2, inet_ntoa(ts->so_remote_addr), ntohs(ts->so_remote_port));
00483 fputs_P(st_P, stream);
00484 fputs("</TD></TR>\r\n", stream);
00485 fflush(stream);
00486 }
00487
00488 fputs_P(foot, stream);
00489 fflush(stream);
00490
00491 return 0;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 int ShowForm(FILE * stream, REQUEST * req)
00504 {
00505 static prog_char html_head[] = "<HTML><BODY><BR><H1>Form Result</H1><BR><BR>";
00506 static prog_char html_body[] = "<BR><BR><p><a href=\"../index.html\">return to main</a></BODY></HTML></p>";
00507
00508 NutHttpSendHeaderTop(stream, req, 200, "Ok");
00509 NutHttpSendHeaderBot(stream, html_mt, -1);
00510
00511
00512 fputs_P(html_head, stream);
00513
00514 if (req->req_query) {
00515 char *name;
00516 char *value;
00517 int i;
00518 int count;
00519
00520 count = NutHttpGetParameterCount(req);
00521
00522 for (i = 0; i < count; i++) {
00523 name = NutHttpGetParameterName(req, i);
00524 value = NutHttpGetParameterValue(req, i);
00525
00526
00527
00528 #ifdef __IMAGECRAFT__
00529 fprintf(stream, "%s: %s<BR>\r\n", name, value);
00530 #else
00531 fprintf_P(stream, PSTR("%s: %s<BR>\r\n"), name, value);
00532 #endif
00533 }
00534 }
00535
00536 fputs_P(html_body, stream);
00537 fflush(stream);
00538
00539 return 0;
00540 }
00541
00554 THREAD(Service, arg)
00555 {
00556 TCPSOCKET *sock;
00557 FILE *stream;
00558 u_char id = (u_char) ((uptr_t) arg);
00559
00560
00561
00562
00563 for (;;) {
00564
00565
00566
00567
00568 if ((sock = NutTcpCreateSocket()) == 0) {
00569 printf("[%u] Creating socket failed\n", id);
00570 NutSleep(5000);
00571 continue;
00572 }
00573
00574
00575
00576
00577
00578 NutTcpAccept(sock, 80);
00579 #if defined(__AVR__)
00580 printf("[%u] Connected, %u bytes free\n", id, NutHeapAvailable());
00581 #else
00582 printf("[%u] Connected, %lu bytes free\n", id, NutHeapAvailable());
00583 #endif
00584
00585
00586
00587
00588
00589 #if defined(__AVR__)
00590 while (NutHeapAvailable() < 8192) {
00591 #else
00592 while (NutHeapAvailable() < 4096) {
00593 #endif
00594 printf("[%u] Low mem\n", id);
00595 NutSleep(1000);
00596 }
00597
00598
00599
00600
00601 if ((stream = _fdopen((int) ((uptr_t) sock), "r+b")) == 0) {
00602 printf("[%u] Creating stream device failed\n", id);
00603 } else {
00604
00605
00606
00607
00608
00609
00610 NutHttpProcessRequest(stream);
00611
00612
00613
00614
00615 fclose(stream);
00616 }
00617
00618
00619
00620
00621 NutTcpCloseSocket(sock);
00622 printf("[%u] Disconnected\n", id);
00623 }
00624 }
00625
00631 int main(void)
00632 {
00633 u_long baud = 115200;
00634 u_char i;
00635
00636
00637
00638
00639 NutRegisterDevice(&DEV_DEBUG, 0, 0);
00640 freopen(DEV_DEBUG_NAME, "w", stdout);
00641 _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00642 NutSleep(200);
00643 printf("\n\nNut/OS %s HTTP Daemon...", NutVersionString());
00644
00645 #ifdef NUTDEBUG
00646 NutTraceTcp(stdout, 0);
00647 NutTraceOs(stdout, 0);
00648 NutTraceHeap(stdout, 0);
00649 NutTracePPP(stdout, 0);
00650 #endif
00651
00652
00653
00654
00655 if (NutRegisterDevice(&DEV_ETHER, 0, 0)) {
00656 puts("Registering device failed");
00657 }
00658
00659 printf("Configure %s...", DEV_ETHER_NAME);
00660 if (NutNetLoadConfig(DEV_ETHER_NAME)) {
00661 u_char mac[] = MY_MAC;
00662
00663 printf("initial boot...");
00664 #ifdef USE_DHCP
00665 if (NutDhcpIfConfig(DEV_ETHER_NAME, mac, 60000))
00666 #endif
00667 {
00668 u_long ip_addr = inet_addr(MY_IPADDR);
00669 u_long ip_mask = inet_addr(MY_IPMASK);
00670 u_long ip_gate = inet_addr(MY_IPGATE);
00671
00672 printf("No DHCP...");
00673 if (NutNetIfConfig(DEV_ETHER_NAME, mac, ip_addr, ip_mask) == 0) {
00674
00675 if(ip_gate) {
00676 printf("hard coded gate...");
00677 NutIpRouteAdd(0, 0, ip_gate, &DEV_ETHER);
00678 }
00679 puts("OK");
00680 }
00681 else {
00682 puts("failed");
00683 }
00684 }
00685 }
00686 else {
00687 #ifdef USE_DHCP
00688 if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) {
00689 puts("failed");
00690 }
00691 else {
00692 puts("OK");
00693 }
00694 #else
00695 if (NutNetIfConfig(DEV_ETHER_NAME, 0, 0, confnet.cdn_ip_mask)) {
00696 puts("failed");
00697 }
00698 else {
00699 puts("OK");
00700 }
00701 #endif
00702 }
00703 printf("%s ready\n", inet_ntoa(confnet.cdn_ip_addr));
00704
00705 #ifdef USE_DISCOVERY
00706 NutRegisterDiscovery((u_long)-1, 0, DISF_INITAL_ANN);
00707 #endif
00708
00709
00710
00711
00712 NutRegisterDevice(&MY_FSDEV, 0, 0);
00713
00714 #ifdef MY_BLKDEV
00715
00716 printf("Registering block device '" MY_BLKDEV_NAME "'...");
00717 if (NutRegisterDevice(&MY_BLKDEV, 0, 0)) {
00718 puts("failed");
00719 for (;;);
00720 }
00721 puts("OK");
00722
00723
00724 printf("Mounting block device '" MY_BLKDEV_NAME ":1/" MY_FSDEV_NAME "'...");
00725 if (_open(MY_BLKDEV_NAME ":1/" MY_FSDEV_NAME, _O_RDWR | _O_BINARY) == -1) {
00726 puts("failed");
00727 for (;;);
00728 }
00729 puts("OK");
00730 #endif
00731
00732 #ifdef MY_HTTPROOT
00733
00734 printf("Registering HTTP root '" MY_HTTPROOT "'...");
00735 if (NutRegisterHttpRoot(MY_HTTPROOT)) {
00736 puts("failed");
00737 for (;;);
00738 }
00739 puts("OK");
00740 #endif
00741
00742
00743
00744
00745
00746 NutRegisterCgi("test.cgi", ShowQuery);
00747
00748
00749
00750
00751
00752 NutRegisterCgi("threads.cgi", ShowThreads);
00753 NutRegisterCgi("timers.cgi", ShowTimers);
00754 NutRegisterCgi("sockets.cgi", ShowSockets);
00755
00756
00757
00758
00759 NutRegisterCgi("form.cgi", ShowForm);
00760
00761
00762
00763
00764
00765 NutRegisterAuth("cgi-bin", "root:root");
00766
00767
00768
00769
00770 NutRegisterSsi();
00771 NutRegisterAsp();
00772 NutRegisterAspCallback(ASPCallback);
00773
00774
00775
00776 for (i = 1; i <= 4; i++) {
00777 char thname[] = "httpd0";
00778
00779 thname[5] = '0' + i;
00780 NutThreadCreate(thname, Service, (void *) (uptr_t) i, NUT_THREAD_MAINSTACK);
00781 }
00782
00783
00784
00785
00786 NutThreadSetPriority(254);
00787 for (;;) {
00788 NutSleep(60000);
00789 }
00790 }