Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1880180
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
36 KB
Subscribers
None
View Options
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> <a href=\"/1/stop\">Stop</a> <a href=\"/1/down\">Down</a><br>"
+ "Blind 2: <a href=\"/2/up\">Up</a> <a href=\"/2/stop\">Stop</a> <a href=\"/2/down\">Down</a><br>"
+ "Blind 3: <a href=\"/3/up\">Up</a> <a href=\"/3/stop\">Stop</a> <a href=\"/3/down\">Down</a><br>"
+ "Blind 4: <a href=\"/4/up\">Up</a> <a href=\"/4/stop\">Stop</a> <a href=\"/4/down\">Down</a><br>"
+ "Blind 5: <a href=\"/5/up\">Up</a> <a href=\"/5/stop\">Stop</a> <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> <br>";
+static const uint8_t c_HTTP_OK[] = "OK<br> <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
Details
Attached
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)
Attached To
rBC BlindControl
Event Timeline
Log In to Comment