Page MenuHomePhabricator

No OneTemporary

diff --git a/ethernet.c b/ethernet.c
--- a/ethernet.c
+++ b/ethernet.c
@@ -1,198 +1,205 @@
/*
* Simple socket server for FreeRTOS based on the Arduino Ethernet Library
* (c) 2011 Andreas Boehler <andreas@aboehler.at>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include "ethernet.h"
#include "main.h"
/**
* \file ethernet.c
* \brief Main ethernet source code
* This file contains the main ethernet handling code.
*/
/********************
* Global variables *
********************/
uint8_t eth_state[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; ///< Ethernet states
uint16_t eth_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; ///< Ethernet ports
uint8_t ethernet_init(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)
{
w5100_init();
w5100_setMACAddress(mac);
w5100_setIPAddress(ip);
w5100_setGatewayIp(gateway);
w5100_setSubnetMask(subnet);
return TRUE;
}
uint8_t socket_server_init(SOCKET s, uint16_t port)
{
if(w5100_readSnSR(s) == SNSR_CLOSED)
{
eth_server_port[s] = port;
socket_server_create_socket(s, SNMR_TCP, eth_server_port[s], 0);
if(socket_server_listen(s))
return TRUE;
else
return FALSE;
}
return FALSE;
}
uint8_t socket_server_socket_status(SOCKET s)
{
return w5100_readSnSR(s);
}
uint8_t socket_server_create_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
{
if((protocol == SNMR_TCP) || (protocol == SNMR_UDP) || (protocol == SNMR_IPRAW) || (protocol == SNMR_MACRAW) || (protocol == SNMR_PPPOE))
{
socket_server_close_socket(s);
w5100_writeSnMR(s, protocol | flag);
if(port != 0)
w5100_writeSnPORT(s, port);
else
w5100_writeSnPORT(s, 80); // We hardcode a default port here
w5100_execCmdSn(s, Sock_OPEN);
return TRUE;
}
else
return FALSE;
}
uint8_t socket_server_close_socket(SOCKET s)
{
w5100_execCmdSn(s, Sock_CLOSE);
w5100_writeSnIR(s, 0xFF);
return TRUE;
}
+uint8_t socket_server_disconnect_socket(SOCKET s)
+{
+ w5100_execCmdSn(s, Sock_DISCON);
+ return TRUE;
+}
+
+
uint8_t socket_server_listen(SOCKET s)
{
if(w5100_readSnSR(s) != SNSR_INIT)
return FALSE;
else
w5100_execCmdSn(s, Sock_LISTEN);
return TRUE;
}
uint8_t socket_server_data_available(SOCKET s)
{
//uint8_t stat = socket_server_socket_status(s);
//if((stat == SNSR_ESTABLISHED) || (stat == SNSR_CLOSE_WAIT))
return w5100_getRXReceivedSize(s);
//else
// return FALSE;
}
uint8_t socket_server_socket_connected(SOCKET s)
{
uint8_t stat = socket_server_socket_status(s);
if((stat == SNSR_ESTABLISHED))
return TRUE;
else
return FALSE;
}
uint8_t socket_server_socket_closed(SOCKET s)
{
uint8_t stat = socket_server_socket_status(s);
if((stat == SNSR_CLOSE_WAIT))
return TRUE;
else
return FALSE;
}
#ifdef USE_ETHERNET_INTERRUPT
uint8_t socket_server_handle_interrupt(void)
{
uint8_t ir = w5100_readIR();
uint8_t sock = 0;
uint8_t sr = 0;
uint8_t i;
for(i=0; i<MAX_SOCK_NUM; i++)
{
if(ir & (1<<i))
{
sr = w5100_readSnIR(i);
sock = i;
}
}
if(sock != MAX_SOCK_NUM)
{
w5100_writeSnIR(sock, sr);
return sock;
}
else
{
return FALSE;
}
}
#endif
uint16_t socket_server_write(SOCKET s, uint8_t *buffer, size_t size)
{
uint16_t ret = 0;
uint16_t freesize = 0;
if(socket_server_socket_status(s) == SNSR_ESTABLISHED)
{
if(size > SSIZE)
ret = SSIZE;
else
ret = size;
freesize = w5100_getTXFreeSize(s);
if(freesize < ret)
ret = 0;
/*
do
{
freesize = w5100_getTXFreeSize(s);
stat = w5100_readSnSR(s);
if((stat != SNSR_ESTABLISHED) && (stat != SNSR_CLOSE_WAIT))
{
ret = 0;
break;
}
}
while(freesize < ret);
*/
w5100_send_data_processing(s, (uint8_t *) buffer, ret);
w5100_execCmdSn(s, Sock_SEND);
while((w5100_readSnIR(s) & SNIR_SEND_OK) != SNIR_SEND_OK)
{
if(w5100_readSnSR(s) == SNSR_CLOSED)
{
socket_server_close_socket(s);
return FALSE;
}
}
w5100_writeSnIR(s, SNIR_SEND_OK);
return ret;
}
return FALSE;
}
uint16_t socket_server_receive(SOCKET s, uint8_t *buf, uint16_t len)
{
uint16_t ret = FALSE;
if(len>0)
{
w5100_recv_data_processing(s, buf, len, 0);
w5100_execCmdSn(s, Sock_RECV);
ret = len;
}
return ret;
}
diff --git a/ethernet.h b/ethernet.h
--- a/ethernet.h
+++ b/ethernet.h
@@ -1,197 +1,210 @@
/*
* Simple socket server for FreeRTOS based on the Arduino Ethernet Library
* (c) 2011 Andreas Boehler <andreas@aboehler.at>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
/**
* \file ethernet.h
* Simple socket server for FreeRTOS based on the Arduino Ethernet Library for the
* W5100 Ethernet controller.
*/
#ifndef ETHERNET_H
#define ETHERNET_H
#include "w5100.h"
/**
* ethernet.h
*
* <pre>ethernet_init(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)</pre>
*
* <i>Function</i> that initializes the ethernet controller with the given parameters.
*
* @param mac Pointer to a byte holding the mac address of the ethernet controller
* @param ip Pointer to an array of bytes holding the IP address for the ethernet controller
* @param gateway Pointer to an array of bytes holding the Gateway IP Address
* @param subnet Pointer to an array of bytes holding the Subnet address
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t ethernet_init(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet);
/**
* ethernet.h
*
* <pre>socket_server_init(uint16_t port)</pre>
*
* <i>Function</i> that initializes a new socket server on the given port.
*
* @param port Integer that specifies the Port Number to create
* @return Socket Number +1 on success, 0 on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_init(SOCKET s, uint16_t port);
/**
* ethernet.h
*
* <pre>socket_server_create_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)</pre>
*
* <i>Function</i> used e.g. by socker_server_init that creates a new socket server on the
* specified socket number using given protocol, port and flags.
* If the socket is already opened, it is automatically closed.
*
* @param s The socket number to create (0-3)
* @param protocol The protocol the socket should use
* @param port The port the new socket should listen one
* @param flag Additional flags to use
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_create_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag);
/**
* ethernet.h
*
* <pre>socket_server_close_socket(SOCKET s)</pre>
*
* <i>Function</i> that closes a previously opened socket.
*
* @param s The socket to close
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_close_socket(SOCKET s);
/**
* ethernet.h
*
+ * <pre>socket_server_disconnect_socket(SOCKET s)</pre>
+ *
+ * <i>Function</i> that disconnects a previously connected socket.
+ *
+ * @param s The socket to disconnect
+ * @return TRUE on success, FALSE on failure.
+ * \ingroup Ethernet
+ */
+uint8_t socket_server_disconnect_socket(SOCKET s);
+
+/**
+ * ethernet.h
+ *
* <pre>socket_server_listen(SOCKET s)</pre>
*
* <i>Function</i> to start listening on the given socket.
*
* @param s The socket number to start listening on
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_listen(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_socket_status(SOCKET s)</pre>
*
* <i>Function</i> that checks the status of a given socket.
*
* @param s The socket number to check.
* @return The status of the socket
* \ingroup Ethernet
*/
uint8_t socket_server_socket_status(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_socket_connected(SOCKET s)</pre>
*
* <i>Function</i> that checks whether a socket is connected or not.
*
* @param s The socket number to check
* @return TRUE if a node is connected, FALSE if nothing is connected to the socket.
* \ingroup Ethernet
*/
uint8_t socket_server_socket_connected(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_socket_closed(SOCKET s)</pre>
*
* <i>Function</i> that checks whether a given socket is closed or no.
*
* @param s The socket number to check
* @return TRUE if the socket's status is closed, otherwise FALSE.
* \ingroup Ethernet
*/
uint8_t socket_server_socket_closed(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_data_available(SOCKET s)</pre>
*
* <i>Function</i> that checks if and how many data is available on a given socket.
*
* @param s The socket number to check
* @return FALSE if no data is available, otherwise the number of bytes that have been received.
* \ingroup Ethernet
*/
uint8_t socket_server_data_available(SOCKET s);
#ifdef USE_ETHERNET_INTERRUPT
/**
* ethernet.h
*
* <pre>socket_server_handle_interrupt(void)</pre>
*
* <i>Function</i> that handles the W5100 interrupt. It reads the interrupt register,
* extracts the socket number the interrupt happened on and clears the interrupt register
* (by mirroring the register values back).
*
* @return The socket number if successful, otherwise FALSE
* \warning If the socket number is 0, it might be misinterpreted as FALSE!
* \ingroup Ethernet
*/
uint8_t socket_server_handle_interrupt(void);
#endif
/**
* ethernet.h
*
* <pre>socket_server_write(SOCKET s, uint8_t *buffer, size_t size)</pre>
*
* <i>Function</i> that writes a character array, buffer, of length size to a given socket.
*
* @param s The socket to write to
* @param buffer Pointer to an array of uint8_t that holds the data
* @param size The length of the buffer array
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint16_t socket_server_write(SOCKET s, uint8_t *buffer, size_t size);
/**
* ethernet.h
*
* <pre>socket_server_receive(SOCKET s, uint8_t *buf, uint16_t len)</pre>
*
* <i>Function</i> that receives a given number of bytes from a given socket to the
* buffer specified.
*
* @param s The socket to receive from
* @param buf Pointer to a character Array to store the bytes to
* @param len Maximum number of characters to receive, usually retrieved by socket_server_data_available
* \ingroup Ethernet
*/
uint16_t socket_server_receive(SOCKET s, uint8_t *buf, uint16_t len);
#endif //ETHERNET_H
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
@@ -1,612 +1,796 @@
/*
- * This is COSMICrtOS based on FreeRTOS port to ATmega2560.
- * (c) 2011 Andreas Boehler <andreas@aboehler.at>
+ * This is BlindControl based on Aduino Ethernet / Arduino Mega2560.
+ * (c) 2014 Andreas Boehler <andreas@aboehler.at>
+ *
+ * v1.0 2014/01/30
+ * Added HTTP Interface (max. 2 sockets)
+ * Reduced Telnet sockets to 2
*
- * ATTENTION: Software licenses apply! GPL is probably incompatible
- * with our NDA! Can we link to a binary blob instead?
+ * v0.3 2014/01/28
+ * Added up to 4 socket connections
+ *
+ * v0.2 2014/01/20
+ * Added Ariadne Bottloader support
+ * and ported NetEEPROM library to plain C
+ *
+ * v0.1 2014/01/15
+ * Initial version with telnet support
+ * Based on W5100 code from the Arduino library, ported to plain C
*/
-// FIXME: Get rid of FreeRTOS
#include <stdlib.h>
#include <string.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include "iomacro.h"
#include "main.h"
#include "neteeprom.h"
#include "ethernet.h"
volatile int gEthFired = FALSE;
+/* Status Codes */
+static const uint8_t c_HTTP_200_OK[] = "HTTP/1.0 200 OK\r\n";
+
+/* Cache Control */
+static const uint8_t c_HTTP_CacheControl_NoCache[] = "Pragma: no-cache\r\nExpires: Fri, 01 Jan 1990 00:00:00 GMT\r\nCache-Control: no-cache, must-revalidate\r\n";
+
+/* Content Types */
+static const uint8_t c_HTTP_Content_HTML[] = "Content-Type: text/html\r\n";
+static const uint8_t c_HTTP_ConnClose[] = "Connection: close\r\n";
+
+/* Empty Line */
+static const uint8_t c_HTTP_EmptyLine[] = "\r\n";
+
+static const uint8_t c_HTTP_IndexPage1[] = "<html><head><title>BlindControl</title></head>\n<body>";
+static const uint8_t c_HTTP_IndexPage2[] =
+ "Blind 1: <a href=\"/1/up\">Up</a> &nbsp; <a href=\"/1/stop\">Stop</a> &nbsp; <a href=\"/1/down\">Down</a><br>"
+ "Blind 2: <a href=\"/2/up\">Up</a> &nbsp; <a href=\"/2/stop\">Stop</a> &nbsp; <a href=\"/2/down\">Down</a><br>"
+ "Blind 3: <a href=\"/3/up\">Up</a> &nbsp; <a href=\"/3/stop\">Stop</a> &nbsp; <a href=\"/3/down\">Down</a><br>"
+ "Blind 4: <a href=\"/4/up\">Up</a> &nbsp; <a href=\"/4/stop\">Stop</a> &nbsp; <a href=\"/4/down\">Down</a><br>"
+ "Blind 5: <a href=\"/5/up\">Up</a> &nbsp; <a href=\"/5/stop\">Stop</a> &nbsp; <a href=\"/5/down\">Down</a><br>"
+ "</body></html>\r\n";
+static const uint8_t c_HTTP_OutOfRange[] = "Selected blind is out of range.<br>&nbsp;<br>";
+static const uint8_t c_HTTP_OK[] = "OK<br>&nbsp;<br>";
#define TOGGLE_DELAY 300
#define INCR_DELAY 200
#define CMD_STOP 5
#define CMD_SELECT 6
#define CMD_UP 7
#define CMD_DOWN 8
#ifdef USE_MEGA2560 // ATMega2560 (Arduino Mega2560) defines
#define AI_PIN0 F,0
#define AI_PIN1 F,1
#define AI_PIN2 F,2
#define AI_PIN3 F,3
#define DO_PIN_STOP E,3
#define DO_PIN_SELECT H,3
#define DO_PIN_UP H,4
#define DO_PIN_DOWN H,5
#else // ATMega328p (Arduino Ethernet) defines
#define AI_PIN0 C,0
#define AI_PIN1 C,1
#define AI_PIN2 C,2
#define AI_PIN3 C,3
#define DO_PIN_STOP D,5
#define DO_PIN_SELECT D,6
#define DO_PIN_UP D,7
#define DO_PIN_DOWN B,0
#endif
#ifdef USE_ETHERNET_INTERRUPT
/***************************************
* Helper function to setup interrupts *
***************************************/
void setupExternalInterrupts(void)
{
EICRB |= (1 << ISC41); // Enable falling edge interrupt
EIMSK |= (1 << INT4); // enable external interrupt 4
}
/****************************************************
* Setup the interrupt handler for ethernet traffic *
****************************************************/
ISR(INT4_vect)
{
gEthFired = TRUE;
}
#endif
/************************************************
* Setup and initialize the ethernet controller *
************************************************/
void setupEthernet(void)
{
//uint8_t mac[] = { 0x00, 0x01, 0x02, 0x0D, 0x74, 0x49 };
//uint8_t ip[] = { 192, 168, 1, 30 };
//uint8_t gateway[] = { 192, 168, 1, 1 };
//uint8_t subnet[] = { 255, 255, 255, 0 };
uint8_t mac[6];
uint8_t ip[4];
uint8_t gateway[4];
uint8_t subnet[4];
- SOCKET s;
eepromReadMAC(mac);
eepromReadIP(ip);
eepromReadGW(gateway);
eepromReadSN(subnet);
if(!eepromNetSigIsSet())
{
eepromWriteIP(ip);
eepromWriteMAC(mac);
eepromWriteGW(gateway);
eepromWriteSN(subnet);
eepromWriteNetSig();
}
if(ethernet_init(mac, ip, gateway, subnet))
{
- for(s = 0; s<MAX_SOCK_NUM; s++)
- {
- socket_server_init(s, SOCK_PORT);
- }
+ // We have two socket ports and two ethernet ports
+ socket_server_init(0, SOCK_PORT);
+ socket_server_init(1, SOCK_PORT);
+ socket_server_init(2, HTTP_PORT);
+ socket_server_init(3, HTTP_PORT);
}
}
/*****************
* Main function *
*****************/
int main( void )
{
// Setup registers for input and output
setupIOPorts();
#ifdef USE_ETHERNET_INTERRUPT
setupExternalInterrupts();
#endif
if(spi_init())
setupEthernet();
#ifdef USE_ETHERNET_INTERRUPT
sei();
#endif
uint8_t new_connect[MAX_SOCK_NUM];
uint8_t connected[MAX_SOCK_NUM];
uint8_t i;
uint16_t len;
SOCKET sock;
+ uint8_t ret;
unsigned char clientline[BUF_SIZE];
for(i=0; i < MAX_SOCK_NUM; i++)
{
new_connect[i] = TRUE;
connected[i] = FALSE;
}
for( ;; )
{
#ifndef USE_ETHERNET_INTERRUPT
for(i=0; i<MAX_SOCK_NUM; i++)
{
if(socket_server_socket_connected(i))
{
if((new_connect[i]) || (socket_server_data_available(i)))
{
gEthFired = TRUE;
sock = i;
break;
}
}
}
#endif
if(gEthFired)
{
gEthFired = FALSE;
#ifdef USE_ETHERNET_INTERRUPT
sock = socket_server_handle_interrupt();
#endif
connected[sock] = socket_server_socket_connected(sock);
if(connected[sock])
{
if(new_connect[sock])
{
- socket_server_write(sock, (unsigned char*)"BlindControl ready\n", (uint16_t)19);
+ if((sock == 0) || (sock == 1)) // Send greeter only for telnet sessions
+ socket_server_write(sock, (unsigned char*)"BlindControl ready\n", (uint16_t)19);
new_connect[sock] = FALSE;
}
}
else
{
if (!new_connect[sock])
new_connect[sock] = TRUE;
if(socket_server_socket_closed(sock))
{
socket_server_close_socket(sock);
- socket_server_init(sock, SOCK_PORT);
+ if((sock == 0) || (sock == 1))
+ socket_server_init(sock, SOCK_PORT);
+ else
+ socket_server_init(sock, HTTP_PORT);
}
}
if(connected[sock] && (len = socket_server_data_available(sock)))
{
+
if(len >= BUF_SIZE)
len = BUF_SIZE-1;
socket_server_receive(sock, clientline, len);
clientline[len] = '\0';
- if(!handle_req(sock, (signed char*)clientline))
+ if((sock == 0) || (sock == 1))
+ ret = handle_req(sock, (signed char*)clientline); // Socket Handling Code
+ else
+ ret = handle_http(sock, (signed char*)clientline); // Handle HTTP Code
+ if(!ret)
{
+ socket_server_disconnect_socket(sock);
socket_server_close_socket(sock);
new_connect[sock] = TRUE;
- socket_server_init(sock, SOCK_PORT);
+ if((sock == 0) || (sock == 1))
+ socket_server_init(sock, SOCK_PORT);
+ else
+ socket_server_init(sock, HTTP_PORT);
}
}
}
}
return 0;
}
+/***********************
+ * Handle HTTP Request *
+ ***********************/
+int handle_http(SOCKET sock, signed char *clientline)
+{
+ int blindNum;
+ uint8_t* u8temp;
+ int all = FALSE;
+ int i;
+ int cmd;
+
+ u8temp = strtok(clientline, " /&\r\n");
+
+ if(strncmp(u8temp, "GET", 3) == 0) // GET Request
+ {
+ u8temp = strtok(NULL, " /&\r\n");
+ if(strncmp(u8temp, "HTTP", 4) == 0)
+ {
+ socket_server_write(sock, (uint8_t*)c_HTTP_200_OK, strlen(c_HTTP_200_OK));
+ socket_server_write(sock, (uint8_t*)c_HTTP_CacheControl_NoCache, strlen(c_HTTP_CacheControl_NoCache));
+ socket_server_write(sock, (uint8_t*)c_HTTP_Content_HTML, strlen(c_HTTP_Content_HTML));
+ socket_server_write(sock, (uint8_t*)c_HTTP_ConnClose, strlen(c_HTTP_ConnClose));
+
+
+ /* Add an empty line */
+ socket_server_write(sock, (uint8_t*)c_HTTP_EmptyLine, strlen(c_HTTP_EmptyLine));
+
+ socket_server_write(sock, (uint8_t*)c_HTTP_IndexPage1, strlen(c_HTTP_IndexPage1));
+ socket_server_write(sock, (uint8_t*)c_HTTP_IndexPage2, strlen(c_HTTP_IndexPage2));
+ return FALSE;
+ }
+ if(strncmp(u8temp, "all", 3) == 0)
+ {
+ all = TRUE;
+ }
+ else
+ {
+ blindNum = atoi(u8temp);
+ if((blindNum > 5) || (blindNum < 0))
+ {
+ socket_server_write(sock, (uint8_t*)c_HTTP_200_OK, strlen(c_HTTP_200_OK));
+ socket_server_write(sock, (uint8_t*)c_HTTP_CacheControl_NoCache, strlen(c_HTTP_CacheControl_NoCache));
+ socket_server_write(sock, (uint8_t*)c_HTTP_Content_HTML, strlen(c_HTTP_Content_HTML));
+ socket_server_write(sock, (uint8_t*)c_HTTP_ConnClose, strlen(c_HTTP_ConnClose));
+
+ /* Add an empty line */
+ socket_server_write(sock, (uint8_t*)c_HTTP_EmptyLine, strlen(c_HTTP_EmptyLine));
+
+ socket_server_write(sock, (uint8_t*)c_HTTP_IndexPage1, strlen(c_HTTP_IndexPage1));
+ socket_server_write(sock, (uint8_t*)c_HTTP_OutOfRange, strlen(c_HTTP_OutOfRange));
+ socket_server_write(sock, (uint8_t*)c_HTTP_IndexPage2, strlen(c_HTTP_IndexPage2));
+ return FALSE;
+ }
+ }
+ u8temp = strtok(NULL, " /&\r\n");
+ if(strncmp(u8temp, "up", 2) == 0) // blind up
+ {
+ cmd = CMD_UP;
+ }
+ else if(strncmp(u8temp, "down", 4) == 0) // blind down
+ {
+ cmd = CMD_DOWN;
+ }
+ else if(strncmp(u8temp, "stop", 4) == 0) // blind stop
+ {
+ cmd = CMD_STOP;
+ }
+
+ if(!all)
+ {
+ selectBlindChannel(blindNum);
+ sendCommand(cmd);
+ }
+ else
+ {
+ for(i = 0; i<5; i++)
+ {
+ selectBlindChannel(i);
+ sendCommand(cmd);
+ }
+ }
+ socket_server_write(sock, (uint8_t*)c_HTTP_200_OK, strlen(c_HTTP_200_OK));
+ socket_server_write(sock, (uint8_t*)c_HTTP_CacheControl_NoCache, strlen(c_HTTP_CacheControl_NoCache));
+ socket_server_write(sock, (uint8_t*)c_HTTP_Content_HTML, strlen(c_HTTP_Content_HTML));
+ socket_server_write(sock, (uint8_t*)c_HTTP_ConnClose, strlen(c_HTTP_ConnClose));
+
+
+ /* Add an empty line */
+ socket_server_write(sock, (uint8_t*)c_HTTP_EmptyLine, strlen(c_HTTP_EmptyLine));
+
+ socket_server_write(sock, (uint8_t*)c_HTTP_IndexPage1, strlen(c_HTTP_IndexPage1));
+ socket_server_write(sock, (uint8_t*)c_HTTP_OK, strlen(c_HTTP_OK));
+ socket_server_write(sock, (uint8_t*)c_HTTP_IndexPage2, strlen(c_HTTP_IndexPage2));
+ }
+ else
+ {
+ // unknown request type
+ }
+
+
+
+ return FALSE; // We always return false, as we close the socket after sending our response.
+}
+
+
+/*********************
+ * Do WatchDog Reset *
+ *********************/
void wdtReset(void)
{
wdt_disable();
wdt_enable(WDTO_2S);
}
+/*************************
+ * Handle Telnet Request *
+ *************************/
int handle_req(SOCKET sock, signed char *clientline)
{
int blindNum;
uint8_t buff[6];
char helpStr[] = "Available Commands: SelectBlind N, BlindUp[ N], BlindDown[ N], "
"BlindStop[ N], BlindIncr[ N], BlindDecr[ N], AllUp, AllDown, AllStop, SetIP, "
"GetIP, SetSN, SetMAC, SetGW, help, reset, reprogram, quit\n\n";
if(strncmp(clientline, "SelectBlind ", 12) == 0)
{
blindNum = atoi(&clientline[12]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(sock, (unsigned char *)"ERR\n", 4);
}
else
{
selectBlindChannel(blindNum);
socket_server_write(sock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindUp ", 8) == 0)
{
blindNum = atoi(&clientline[8]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(sock, (unsigned char *)"ERR\n", 4);
}
else
{
blindUp(blindNum);
socket_server_write(sock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindDown ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(sock, (unsigned char *)"ERR\n", 4);
}
else
{
blindDown(blindNum);
socket_server_write(sock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindStop ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(sock, (unsigned char *)"ERR\n", 4);
}
else
{
blindStop(blindNum);
socket_server_write(sock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindIncr ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(sock, (unsigned char *)"ERR\n", 4);
}
else
{
selectBlindChannel(blindNum);
sendCommand(CMD_UP);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP);
socket_server_write(sock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindDecr ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(sock, (unsigned char *)"ERR\n", 4);
}
else
{
selectBlindChannel(blindNum);
sendCommand(CMD_DOWN);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP);
socket_server_write(sock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindUp", 7) == 0)
{
sendCommand(CMD_UP);
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindDown", 9) == 0)
{
sendCommand(CMD_DOWN);
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindStop", 9) == 0)
{
sendCommand(CMD_STOP);
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindIncr", 9) == 0)
{
sendCommand(CMD_UP);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP);
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindDecr", 9) == 0)
{
sendCommand(CMD_DOWN);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP);
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "AllUp", 5) == 0)
{
for(blindNum=1; blindNum<6; blindNum++)
{
blindUp(blindNum);
}
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "AllDown", 7) == 0)
{
for(blindNum=1; blindNum<6; blindNum++)
{
blindDown(blindNum);
}
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "AllStop", 7) == 0)
{
for(blindNum = 1; blindNum < 6; blindNum++)
{
blindStop(blindNum);
}
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "reset", 5) == 0)
{
wdtReset();
socket_server_write(sock, "OK\n", 3);
return FALSE;
}
else if(strncmp(clientline, "reprogram", 9) == 0)
{
eepromWriteImgBad();
wdtReset();
socket_server_write(sock, "OK\n", 3);
return FALSE;
}
else if(strncmp(clientline, "SetIP", 5) == 0)
{
if(strlen(clientline) > 13)
{
parseAddr(clientline+6, buff, ".");
eepromWriteIP(buff);
if(!eepromNetSigIsSet())
eepromWriteNetSig();
socket_server_write(sock, "OK\n", 3);
}
else
{
socket_server_write(sock, "ERR\n", 4);
}
}
else if(strncmp(clientline, "SetGW", 5) == 0)
{
if(strlen(clientline) > 13)
{
parseAddr(clientline+6, buff, ".");
eepromWriteGW(buff);
if(!eepromNetSigIsSet())
eepromWriteNetSig();
socket_server_write(sock, "OK\n", 3);
}
else
{
socket_server_write(sock, "ERR\n", 4);
}
}
else if(strncmp(clientline, "SetSN", 5) == 0)
{
if(strlen(clientline) > 13)
{
parseAddr(clientline+6, buff, ".");
eepromWriteSN(buff);
if(!eepromNetSigIsSet())
eepromWriteNetSig();
socket_server_write(sock, "OK\n", 3);
}
else
{
socket_server_write(sock, "ERR\n", 4);
}
}
else if(strncmp(clientline, "SetMAC", 6) == 0)
{
if(strlen(clientline) > 13) // FIXME: Must be bigger!
{
parseAddr(clientline+7, buff, ":");
eepromWriteMAC(buff);
if(!eepromNetSigIsSet())
eepromWriteNetSig();
socket_server_write(sock, "OK\n", 3);
}
else
{
socket_server_write(sock, "ERR\n", 4);
}
}
else if(strncmp(clientline, "GetIP", 5) == 0)
{
uint8_t buff2[10];
eepromReadIP(buff);
for(int i=0; i<4; i++)
{
itoa(buff[i], buff2, 10);
socket_server_write(sock, buff2, strlen(buff2));
if(i<3)
socket_server_write(sock, ".", 1);
else
socket_server_write(sock, "\n", 1);
}
socket_server_write(sock, "OK\n", 3);
}
else if(strncmp(clientline, "help", 4) == 0)
{
socket_server_write(sock, helpStr, strlen(helpStr));
}
else if(strncmp(clientline, "quit", 4) == 0)
{
return FALSE;
}
else
{
socket_server_write(sock, "ERR\n", 4);
}
return TRUE;
}
+/******************************************
+ * Retrieve currently select BlindChannel *
+ ******************************************/
int getCurrentBlindChannel(void)
{
int currentChannel = 0;
int readValues;
readValues = readFromADC();
if(readValues == 0)
{
sendCommand(CMD_SELECT);
readValues = readFromADC();
}
switch(readValues)
{
case 1:
currentChannel = 1;
break;
case 2:
currentChannel = 2;
break;
case 4:
currentChannel = 3;
break;
case 8:
currentChannel = 4;
break;
case 15:
currentChannel = 5;
break;
default:
currentChannel = 0;
}
return currentChannel;
}
+
+/************************************
+ * Helper Function to read from ADC *
+ ************************************/
int readFromADC(void)
{
int j;
int channel = 0;
- for(j=0;j<200;j++)
+ for(j=0;j<500;j++)
{
if(!IS_SET(AI_PIN0))
channel |= 0x01;
if(!IS_SET(AI_PIN1))
channel |= 0x02;
if(!IS_SET(AI_PIN2))
channel |= 0x04;
if(!IS_SET(AI_PIN3))
channel |= 0x08;
}
return channel;
}
+/***************************************
+ * Helper Function to select a channel *
+ ***************************************/
int selectBlindChannel(int telisChannel)
{
while(getCurrentBlindChannel() != telisChannel)
sendCommand(CMD_SELECT);
return TRUE;
}
+/*******************************
+ * Helper Function for BlindUp *
+ *******************************/
int blindUp(int telisChannel)
{
selectBlindChannel(telisChannel);
sendCommand(CMD_UP);
return TRUE;
}
+/*********************************
+ * Helper Function for BlindDown *
+ *********************************/
int blindDown(int telisChannel)
{
selectBlindChannel(telisChannel);
sendCommand(CMD_DOWN);
return TRUE;
}
+/*********************************
+ * Helper Function for BlindStop *
+ *********************************/
int blindStop(int telisChannel)
{
selectBlindChannel(telisChannel);
sendCommand(CMD_STOP);
return TRUE;
}
+/*************************************
+ * Helper Function to send a command *
+ *************************************/
int sendCommand(int digitalChannel)
{
switch(digitalChannel)
{
case CMD_STOP:
SET(DO_PIN_STOP);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_STOP);
break;
case CMD_SELECT:
SET(DO_PIN_SELECT);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_SELECT);
break;
case CMD_UP:
SET(DO_PIN_UP);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_UP);
break;
case CMD_DOWN:
SET(DO_PIN_DOWN);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_DOWN);
break;
}
_delay_ms(TOGGLE_DELAY);
return TRUE;
}
/****************************************
* Setup all required I/O Ports for use *
****************************************/
uint8_t setupIOPorts( void )
{
SET_INPUT(AI_PIN0);
SET_INPUT(AI_PIN1);
SET_INPUT(AI_PIN2);
SET_INPUT(AI_PIN3);
RESET(DO_PIN_STOP);
RESET(DO_PIN_SELECT);
RESET(DO_PIN_UP);
RESET(DO_PIN_DOWN);
SET_OUTPUT(DO_PIN_STOP);
SET_OUTPUT(DO_PIN_SELECT);
SET_OUTPUT(DO_PIN_UP);
SET_OUTPUT(DO_PIN_DOWN);
return TRUE;
}
+/******************************************
+ * Helper Function to parse an IP Address *
+ ******************************************/
void parseAddr(signed char *str, uint8_t *ip, char *delim)
{
int i = 0;
char* buff = (char*)malloc(10);
buff = strtok(str, delim);
while (buff != NULL)
{
ip[i] = (uint8_t)atoi(buff);
buff = strtok(NULL, delim);
i++;
}
free(buff);
}
//EOF
diff --git a/main.h b/main.h
--- a/main.h
+++ b/main.h
@@ -1,48 +1,51 @@
#ifndef MAIN_H
#define MAIN_H
#include "w5100.h"
#define TRUE 1
#define FALSE 0
#ifdef USE_MEGA2560 // Arduino Mega2560 defines
#define P_MOSI B,2
#define P_MISO B,3
#define P_SCK B,1
#define P_SS B,0
#define W5100_CS B,4
#define W5100_INT D,2
#else // Arduino Ethernet defines
#define P_MOSI B,3 //B,2
#define P_MISO B,4 //B,3
#define P_SCK B,5 //B,1
#define P_SS B,2 //B,0
#define W5100_CS B,2 //B,4
#define W5100_INT E,4 // D,2
#endif
#define BUF_SIZE 255
#define SOCK_PORT 63543
+#define HTTP_PORT 80
int readADC(int digitalChannel);
int getCurrentBlindChannel(void);
int selectBlindChannel(int telisChannel);
int blindUp(int telisChannel);
int blindDown(int telisChannel);
int blindStop(int telisChannel);
int sendCommand(int digitalChannel);
int readFromADC(void);
void wdtReset(void);
void parseAddr(signed char *str, uint8_t *ip, char *delim);
int main(void);
#ifdef USE_ETHERNET_INTERRUPT
void setupExternalInterrupts(void);
#endif
int handle_req(SOCKET sock, signed char* clientline);
+int handle_http(SOCKET sock, signed char* clientline);
uint8_t setupIOPorts(void);
+
#endif
diff --git a/vera/I_DiySomfy1.xml b/vera/I_DiySomfy1.xml
--- a/vera/I_DiySomfy1.xml
+++ b/vera/I_DiySomfy1.xml
@@ -1,78 +1,79 @@
<?xml version="1.0"?>
<implementation>
<functions>
function lug_startup (lul_device)
- local TELNET_PORT = 63543
ipAddress = luup.devices[lul_device].ip
local blindIds = luup.variable_get( "urn:micasaverde-com:serviceId:DiySomfy1", "BlindIds", lul_device) or ""
if (blindIds == "") then
blindIds = "1,2"
luup.variable_set( "urn:micasaverde-com:serviceId:DiySomfy1", "BlindIds", blindIds, lul_device)
end
if (ipAddress == "") then
luup.log("No ip address for Somfy", 1)
return false, "Set up the IP address for Somfy", "Somfy DiY Blind Interface"
end
luup.log( "Somfy channels are '" .. blindIds)
- luup.io.open(lul_device, ipAddress, TELNET_PORT)
local childDevices = luup.chdev.start(lul_device)
for blindNo in blindIds:gmatch("%d") do
luup.log( "Adding blind #" .. blindNo ..".")
luup.chdev.append( lul_device, childDevices, blindNo, "Blind #"..blindNo, "urn:schemas-micasaverde-com:device:WindowCovering:1", "D_WindowCovering1.xml", "", "", false)
end
luup.chdev.sync(lul_device, childDevices)
end
</functions>
<startup>lug_startup</startup>
<incoming>
<lua>
local response = tostring(lul_data)
luup.log("Response:" .. response)
</lua>
</incoming>
<actionList>
<action>
<serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId>
<name>Up</name>
<run>
- local lul_command = "BlindUp " .. luup.devices[lul_device].id .. "\r"
-
- if (luup.io.write(lul_command) == false) then
+ ipAddress = luup.devices[luup.devices[lul_device].device_num_parent].ip
+ local lul_command = "http://" .. ipAddress .. "/" .. luup.devices[lul_device].id .. "/up"
+
+ if(luup.inet.wget(lul_command, 30) ~= 0) then
luup.log( "Cannot send '" .. tostring(lul_command) .. "'.", 1)
luup.set_failure(true)
return false
end
</run>
</action>
<action>
<serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId>
<name>Down</name>
<run>
- local lul_command = "BlindDown " .. luup.devices[lul_device].id .. "\r"
-
- if (luup.io.write(lul_command) == false) then
+ ipAddress = luup.devices[luup.devices[lul_device].device_num_parent].ip
+ local lul_command = "http://" .. ipAddress .. "/" .. luup.devices[lul_device].id .. "/down"
+
+ if(luup.inet.wget(lul_command, 30) ~= 0) then
luup.log( "Cannot send '" .. tostring(lul_command) .. "'.", 1)
luup.set_failure(true)
return false
end
</run>
</action>
<action>
<serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId>
<name>Stop</name>
<run>
- local lul_command = "BlindStop " .. luup.devices[lul_device].id .. "\r"
-
- if (luup.io.write(lul_command) == false) then
+ ipAddress = luup.devices[luup.devices[lul_device].device_num_parent].ip
+ local lul_command = "http://" .. ipAddress .. "/" .. luup.devices[lul_device].id .. "/stop"
+
+ if(luup.inet.wget(lul_command, 30) ~= 0) then
luup.log( "Cannot send '" .. tostring(lul_command) .. "'.", 1)
luup.set_failure(true)
return false
end
</run>
</action>
</actionList>
</implementation>

File Metadata

Mime Type
text/x-diff
Expires
Fri, Jan 24, 3:06 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
532556
Default Alt Text
(36 KB)

Event Timeline