Esempio n. 1
0
// result code is unused now. always 200 OK
void http_reply(int code, char *data) // rewrite with tcp_ref() 16.12.2014
{
  unsigned pkt = tcp_create_packet(http.tcp_session);
  if(pkt != 0xFF)
  {
    unsigned dlen = strlen(data);
    if(dlen > 1024) dlen = 1024;
    char *p = tcp_ref(pkt, 0);
    char *s = p;
    p += sprintf(p,
      "HTTP/1.1 200 Ok\r\n"
      "Connection: Close\r\n"
      "Cache-Control: no-store, no-cache, must-revalidate\r\n"
      "Expires: Fri, 13 Oct 2000 00:00:00 GMT\r\n"
        );
    if(req_origin[0] != 0)
      p += sprintf(p,
      "Access-Control-Allow-Origin: %s\r\n"
      "Access-Control-Allow-Credentials: true\r\n",
        req_origin );
    p += sprintf(p,
      "Content-Type: %s\r\n"
      "Content-Length: %u\r\n"
      "\r\n",
         http.page->mime,
         dlen
         );
    memcpy(p, data, dlen); p += dlen;
    tcp_send_packet(http.tcp_session, pkt, (unsigned)(p - s));
  }
  tcp_close_session(http.tcp_session);
  http.state = HTTP_COMPLETE;
}
Esempio n. 2
0
void http_exec(void)
{
  switch(http.state)
  {
  case HTTP_SEND_HEADERS:
    http_start_get();
    break;
  case HTTP_SEND_PAGE:
    http_get_pumping(0xff);
    break;
  case HTTP_COMPLETE:
    if(TCP_CONN_IS_CLOSED(http.tcp_session)) http.state = HTTP_IDLE;
    break;
  }
  // sse keep alive
  if(sys_clock_100ms > sse_ping_timer && http_can_send_sse())
  {
    unsigned pkt = tcp_create_packet_sized(sse_sock, 256);
    if(pkt != 0xff)
    {
      unsigned len = sprintf( (char*)tcp_ref(pkt, 0), "event: sse_ping\n""data: -\n\n" );
      tcp_send_packet(sse_sock, pkt, len);
      sse_ping_timer = sys_clock_100ms + 90; // 9s
    }
  }
}
Esempio n. 3
0
void http_responce_options(void) // 16.12.2014
{
  http.state = HTTP_SEND_HEADERS;
  unsigned pkt = tcp_create_packet(http.tcp_session);
  if(pkt == 0xff) return;
  char buf[512];
  char *p = buf;
  p += sprintf(p,
    "HTTP/1.1 200 Ok\r\n"
    "Access-Control-Allow-Origin: %s\r\n"
    "Access-Control-Allow-Credentials: true\r\n"
    "Access-Control-Allow-Methods: OPTIONS, %s\r\n"
    "Content-Type: %s\r\n"
    "Content-Length: 0\r\n"
    "\r\n",
      req_origin,
      (http.page->flags & HTML_FLG_POST) ? "POST" : "GET",
      http.page->mime
             );
  tcp_tx_body_pointer = 0;
  tcp_put_tx_body(pkt, (void*)buf, p - buf);
  tcp_send_packet(http.tcp_session, pkt, tcp_tx_body_pointer);
  tcp_close_session(http.tcp_session);
  http.state = HTTP_COMPLETE;
}
Esempio n. 4
0
static void send_redirect(char *location, unsigned location_len)
{
  if(location_len > 1024) return; // 16.12.2014 moved
  unsigned pkt = tcp_create_packet(http.tcp_session);
  if(pkt == 0xFF) return;
  tcp_tx_body_pointer = 0;
  tcp_put_tx_body(pkt, (unsigned char*)location, location_len);
  tcp_send_packet(http.tcp_session, pkt, location_len);
  tcp_close_session(http.tcp_session);
  http.state = HTTP_COMPLETE;
}
Esempio n. 5
0
void http_get_pumping(unsigned pkt)
{
  struct page_s *page = http.page;

  if(tcp_socket[http.tcp_session].out_in_flight >= 2) return; // 17.05.2011
  if(tcp_socket[http.tcp_session].tcp_state != TCP_ESTABLISHED) return; // 9.05.2013

  if(pkt == 0xFF)
  {
    pkt = tcp_create_packet(http.tcp_session);
    tcp_tx_body_pointer=0;
  }
  if(pkt == 0xFF) return;

  if(http.page->flags & HTML_FLG_CGI) // call service (procedural data generation)
  {
    http.more_data = ((unsigned(*)(unsigned,unsigned))(http.page->addr))(pkt, http.more_data);
    if(http.state == HTTP_IDLE) return; // emergency cancel possibility
  }
  else // send generic http page
  {
#if defined(  HTML_RES_IS_IN_CPU_FLASH  )
    unsigned len = http.page->size - http.sent;
    // unsigned available = (1536 - 128) - tcp_tx_body_pointer;
    unsigned available = (1100 - 14 - 20 - 24)  - tcp_tx_body_pointer; // MTU 1100 // 28.07.2014
    if(len > available) len = available;
    tcp_put_tx_body(pkt, (unsigned char*)page->addr + http.sent, len);
    http.sent += len;
    http.more_data = http.sent < page->size;
#elif defined(  HTML_RES_IS_IN_EEPROM   )
# error "Data in ext. flash is unsupported in this version of http2.c!"
#else
# error "Define HTML_RES_IS_IN_xxxxx macro in http2_def.h!"
#endif
  }
  tcp_send_packet(http.tcp_session, pkt, tcp_tx_body_pointer);
  if(http.more_data == 0)
  {
    // push data, close tcp connection
    tcp_close_session(http.tcp_session);
    http.state = HTTP_COMPLETE;
  }
}
Esempio n. 6
0
void http_responce_err(int code)
{
  char buf[256];
  char *s = buf;
  switch(code)
  {
  case 404:
    s += sprintf(s,"HTTP/1.1 404 Not Found\r\n");
    break;
  case 401:
    s += sprintf(s,
       "HTTP/1.1 401 Unauthorized\r\n"
       "WWW-Authenticate: Basic realm=\"%s\"\r\n",
           device_name);
    if(req_origin[0] != 0)
    {
      s += sprintf(s,
       "Access-Control-Allow-Origin: %s\r\n"
       "Access-Control-Allow-Credentials: true\r\n",
              req_origin);
    }
    break;
  default: // incl. 500
    s += sprintf(s,
      "HTTP/1.1 500 Internal Server Error\r\n"  );
    break;
  }
  s += sprintf(s, "\r\n");
  unsigned pkt = tcp_create_packet(http.tcp_session);
  if(pkt == 0xFF) return;
  unsigned len = (unsigned)(s - buf);
  tcp_tx_body_pointer = 0;
  tcp_put_tx_body(pkt, (unsigned char*)buf, len);
  tcp_send_packet(http.tcp_session, pkt, len);
  tcp_close_session(http.tcp_session);
  http.state = HTTP_COMPLETE;
}
Esempio n. 7
0
//*****************************************************************************************
//
// Function : client_process
// Description : send temparature to web server, this option is disabled by default.
// YOU MUST install webserver and server script before enable this option, 
// I recommented Apache webserver and PHP script. 
// More detail about Apache and PHP installation please visit http://www.avrportal.com/
//
//*****************************************************************************************
void client_process ( void )
{
	WORD dlength;
	// you can change rx,tx buffer size in includes.h
	BYTE rxtx_buffer[MAX_RXTX_BUFFER];

	// wait for send temparature flag is set, this flag set by time_base function (menu.c)
	if ( flag1.bits.send_temp == 0 )
		return;	
	// AVR busy now and wait untill transfer data to web browser completed.
	if ( flag1.bits.syn_is_received )
		return;
	// AVR sent temparature to web server but not found web server on port 80
	//if ( flag1.bits.not_found_server )
	//	return;
	// send SYN to initial connection
	if ( flag1.bits.syn_is_sent == 0 )
	{
		// start arp 
		// server ip was not found on network
		if ( arp_who_is ( rxtx_buffer, (BYTE*)&server_mac, (BYTE*)&server_ip ) == 0 )
		{
			flag1.bits.send_temp = 0;
			return;
		}
	
		// send SYN packet to initial connection
		tcp_send_packet (
			rxtx_buffer,
			(WORD_BYTES){80},						// destination port
			(WORD_BYTES){1200},					// source port
			TCP_FLAG_SYN_V,			// flag
			1,						// (bool)maximum segment size
			1,						// (bool)clear sequence ack number
			0,						// 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
			0,						// tcp data length
			(BYTE*)&server_mac,		// server mac address
			(BYTE*)&server_ip );	// server ip address
		flag1.bits.syn_is_sent = 1;
	}
	// get new packet
	dlength = enc28j60_packet_receive( (BYTE*)&rxtx_buffer, MAX_RXTX_BUFFER );
	
	// no new packet incoming
	if ( dlength == 0 )
	{
		// timeout occured, when SYN has been sent but no response from web server
		// reset send_temp and syn_is_sent flags
		if ( flag1.bits.send_temp_timeout )
		{
			flag1.bits.send_temp_timeout = 0;
			flag1.bits.send_temp = 0;
			flag1.bits.syn_is_sent = 0;
		}
		return;
	}
	
	// check ip packet send to avr or not?
	// accept ip packet only
	if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) == 0 )
	{
		return;
	}

	// check SYNACK flag, after AVR send SYN server response by send SYNACK to AVR
	if ( rxtx_buffer [ TCP_FLAGS_P ] == ( TCP_FLAG_SYN_V | TCP_FLAG_ACK_V ) )
	{
		// send ACK to answer SYNACK
		tcp_send_packet (
					(BYTE*)&rxtx_buffer,
					(WORD_BYTES){80},						// destination port
					(WORD_BYTES){1200},					// source port
					TCP_FLAG_ACK_V,			// flag
					0,						// (bool)maximum segment size
					0,						// (bool)clear sequence ack number
					1,						// 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
					0,						// tcp data length
					(BYTE*)&server_mac,		// server mac address
					(BYTE*)&server_ip );	// server ip address
		// setup http request to server
		dlength = http_put_request( (BYTE*)&rxtx_buffer );
		// send http request packet
		// send packet with PSHACK
		tcp_send_packet (
					(BYTE*)&rxtx_buffer,
					(WORD_BYTES){80},						// destination port
					(WORD_BYTES){1200},					// source port
					TCP_FLAG_ACK_V | TCP_FLAG_PSH_V,			// flag
					0,						// (bool)maximum segment size
					0,						// (bool)clear sequence ack number
					0,						// 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
					dlength,				// tcp data length
					(BYTE*)&server_mac,		// server mac address
					(BYTE*)&server_ip );	// server ip address
		return;
	}
	// after AVR send http request to server, server response by send data with PSHACK to AVR
	// AVR answer by send ACK and FINACK to server
	if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_PSH_V) )
	{
		dlength = tcp_get_dlength( (BYTE*)&rxtx_buffer );

		// send ACK to answer PSHACK from server
		tcp_send_packet (
					(BYTE*)&rxtx_buffer,
					(WORD_BYTES){80},						// destination port
					(WORD_BYTES){1200},					// source port
					TCP_FLAG_ACK_V,			// flag
					0,						// (bool)maximum segment size
					0,						// (bool)clear sequence ack number
					dlength,						// 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
					0,				// tcp data length
					(BYTE*)&server_mac,		// server mac address
					(BYTE*)&server_ip );	// server ip address
		// send finack to disconnect from web server
		
		tcp_send_packet (
					(BYTE*)&rxtx_buffer,
					(WORD_BYTES){80},						// destination port
					(WORD_BYTES){1200},					// source port
					TCP_FLAG_FIN_V|TCP_FLAG_ACK_V,			// flag
					0,						// (bool)maximum segment size
					0,						// (bool)clear sequence ack number
					0,						// (bool)calculate new seq and seqack number
					0,						// tcp data length
					(BYTE*)&server_mac,		// server mac address
					(BYTE*)&server_ip );	// server ip address
		return;
		//menu_flag.bits.send_temp = 0;
		//send_syn = 0;
	}
	// answer FINACK from web server by send ACK to web server
	if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_FIN_V|TCP_FLAG_ACK_V) )
	{
		// send ACK with seqack = 1
		tcp_send_packet (
					(BYTE*)&rxtx_buffer,
					(WORD_BYTES){80},						// destination port
					(WORD_BYTES){1200},					// source port
					TCP_FLAG_ACK_V,			// flag
					0,						// (bool)maximum segment size
					0,						// (bool)clear sequence ack number
					1,						// 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
					0,				// tcp data length
					(BYTE*)&server_mac,		// server mac address
					(BYTE*)&server_ip );	// server ip address
		// temparature has been sent
		// and wait for next schedule to send temparature
		flag1.bits.send_temp = 0;
		flag1.bits.syn_is_sent = 0;
	}
}
Esempio n. 8
0
void http_start_get(void)
{
  http.state = HTTP_SEND_HEADERS;
  unsigned pkt = tcp_create_packet(http.tcp_session);
  if(pkt == 0xff) return;
  tcp_tx_body_pointer=0;
  ADD_HTTP_STRING(pkt,
    "HTTP/1.1 200 Ok\r\n"
    "Connection: Close\r\n");
  if(http.page->flags & HTML_FLG_NOCACHE)
  {
    ADD_HTTP_STRING(pkt,
    "Cache-Control: no-store, no-cache, must-revalidate\r\n"
    "Expires: Fri, 28 Apr 2000 00:00:00 GMT\r\n");
  }
  else
  {
    ADD_HTTP_STRING(pkt,
    "Cache-Control: max-age=10000, private\r\n");
  }
  if(http.page->flags & HTML_FLG_COMPRESSED)
  {
    ADD_HTTP_STRING(pkt,
    "Content-Encoding: gzip\r\n");
  }
  char *p = tcp_ref(pkt, tcp_tx_body_pointer);
  char *s = p;
  p += sprintf(p, "Content-Type: %s\r\n", http.page->mime);
  if(req_origin[0] != 0)
  {
    p += sprintf(p, "Access-Control-Allow-Origin: %s\r\n", req_origin);
    p += sprintf(p, "Access-Control-Allow-Credentials: true\r\n");
  }
  p += sprintf(p, "\r\n"); // end of headers
  tcp_tx_body_pointer += (unsigned)(p - s);
  if(http.page->flags & HTML_FLG_SS_EVENT)
  {
    if(sse_sock != 0xff)
    {
      // prepare old SSE socket to work as new http socket
      if(tcp_socket[sse_sock].tcp_state != TCP_RESERVED)
      {
        tcp_send_flags(TCP_MSK_ACK | TCP_MSK_RST | TCP_MSK_PSH, sse_sock);
        tcp_send_flags(TCP_MSK_ACK | TCP_MSK_RST | TCP_MSK_PSH, sse_sock);
        tcp_clear_connection(sse_sock);
      }
      // pass current http socket to SSE use
      unsigned swap_sock = sse_sock;
      sse_sock = http.tcp_session;
      http.tcp_session = swap_sock;
      // add initial data on SSE channel
      static char sse_retry_cmd[] = "retry: 2000\n\n";
      tcp_put_tx_body(pkt, (void*)sse_retry_cmd, strlen(sse_retry_cmd));
      ((unsigned(*)(unsigned, unsigned))(http.page->addr))(pkt, 0);
      // send 1st reply on SSE channel
      tcp_send_packet(sse_sock, pkt, tcp_tx_body_pointer);
      // start listening on alternative socket
      tcp_socket[http.tcp_session].tcp_state = TCP_LISTEN;
      http.state = HTTP_IDLE;
    }
  }
  else
  {
    http.state = HTTP_SEND_PAGE;
    http.sent = 0;
    http.more_data = 0;
    http_get_pumping(pkt);
  }
}