Example program with HTTPServer and sensor data streaming over TCPSockets, using Donatien Garnier's Net APIs and services code on top of LWIP. Files StreamServer.h and .cpp encapsulate streaming over TCPSockets. Broadcast is done by sendToAll(), and all incoming data is echoed back to the client. Echo code can be replaced with some remote control of the streaming interface. See main() that shows how to periodically send some data to all subscribed clients. To subscribe, a client should open a socket at <mbed_ip> port 123. I used few lines in TCL code to set up a quick sink for the data. HTTP files are served on port 80 concurrently to the streaming.

Dependencies:   mbed

Committer:
iva2k
Date:
Sat Jun 12 06:01:50 2010 +0000
Revision:
0:e614f7875b60
Child:
1:3ee499525aa5

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iva2k 0:e614f7875b60 1
iva2k 0:e614f7875b60 2 /*
iva2k 0:e614f7875b60 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
iva2k 0:e614f7875b60 4
iva2k 0:e614f7875b60 5 Permission is hereby granted, free of charge, to any person obtaining a copy
iva2k 0:e614f7875b60 6 of this software and associated documentation files (the "Software"), to deal
iva2k 0:e614f7875b60 7 in the Software without restriction, including without limitation the rights
iva2k 0:e614f7875b60 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
iva2k 0:e614f7875b60 9 copies of the Software, and to permit persons to whom the Software is
iva2k 0:e614f7875b60 10 furnished to do so, subject to the following conditions:
iva2k 0:e614f7875b60 11
iva2k 0:e614f7875b60 12 The above copyright notice and this permission notice shall be included in
iva2k 0:e614f7875b60 13 all copies or substantial portions of the Software.
iva2k 0:e614f7875b60 14
iva2k 0:e614f7875b60 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
iva2k 0:e614f7875b60 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
iva2k 0:e614f7875b60 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
iva2k 0:e614f7875b60 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
iva2k 0:e614f7875b60 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
iva2k 0:e614f7875b60 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
iva2k 0:e614f7875b60 21 THE SOFTWARE.
iva2k 0:e614f7875b60 22 */
iva2k 0:e614f7875b60 23
iva2k 0:e614f7875b60 24 #include "PPPNetIf.h"
iva2k 0:e614f7875b60 25 #include "mbed.h"
iva2k 0:e614f7875b60 26 #include "ppp/ppp.h"
iva2k 0:e614f7875b60 27 #include "lwip/init.h"
iva2k 0:e614f7875b60 28 #include "lwip/sio.h"
iva2k 0:e614f7875b60 29
iva2k 0:e614f7875b60 30 #define __DEBUG
iva2k 0:e614f7875b60 31 #include "dbg/dbg.h"
iva2k 0:e614f7875b60 32
iva2k 0:e614f7875b60 33 #include "netCfg.h"
iva2k 0:e614f7875b60 34 #if NET_PPP
iva2k 0:e614f7875b60 35
iva2k 0:e614f7875b60 36 #define PPP_TIMEOUT 60000
iva2k 0:e614f7875b60 37
iva2k 0:e614f7875b60 38 #define BUF_SIZE 128
iva2k 0:e614f7875b60 39
iva2k 0:e614f7875b60 40 PPPNetIf::PPPNetIf(GPRSModem* pIf) : LwipNetIf(), m_pIf(pIf),/* m_open(false),*/ m_connected(false), m_status(PPP_DISCONNECTED), m_fd(0) //, m_id(0)
iva2k 0:e614f7875b60 41 {
iva2k 0:e614f7875b60 42 //FIXME: Check static refcount
iva2k 0:e614f7875b60 43 pppInit();
iva2k 0:e614f7875b60 44 m_buf = new uint8_t[BUF_SIZE];
iva2k 0:e614f7875b60 45 }
iva2k 0:e614f7875b60 46
iva2k 0:e614f7875b60 47 PPPNetIf::~PPPNetIf()
iva2k 0:e614f7875b60 48 {
iva2k 0:e614f7875b60 49 delete[] m_buf;
iva2k 0:e614f7875b60 50 }
iva2k 0:e614f7875b60 51
iva2k 0:e614f7875b60 52 #if 0
iva2k 0:e614f7875b60 53 PPPErr PPPNetIf::open(Serial* pSerial)
iva2k 0:e614f7875b60 54 {
iva2k 0:e614f7875b60 55 GPRSErr err = m_pIf->open(pSerial);
iva2k 0:e614f7875b60 56 if(err)
iva2k 0:e614f7875b60 57 return PPP_MODEM;
iva2k 0:e614f7875b60 58 m_open = true;
iva2k 0:e614f7875b60 59 #if 0
iva2k 0:e614f7875b60 60 m_id = sioMgr::registerSerialIf(this);
iva2k 0:e614f7875b60 61 if(!m_id)
iva2k 0:e614f7875b60 62 {
iva2k 0:e614f7875b60 63 close();
iva2k 0:e614f7875b60 64 return PPP_CLOSED;
iva2k 0:e614f7875b60 65 }
iva2k 0:e614f7875b60 66 #endif
iva2k 0:e614f7875b60 67 return PPP_OK;
iva2k 0:e614f7875b60 68 }
iva2k 0:e614f7875b60 69 #endif
iva2k 0:e614f7875b60 70
iva2k 0:e614f7875b60 71
iva2k 0:e614f7875b60 72 PPPErr PPPNetIf::GPRSConnect(const char* apn, const char* userId, const char* password) //Connect using GPRS
iva2k 0:e614f7875b60 73 {
iva2k 0:e614f7875b60 74 LwipNetIf::init();
iva2k 0:e614f7875b60 75 //TODO: Tell ATIf that we get ownership of the serial port
iva2k 0:e614f7875b60 76
iva2k 0:e614f7875b60 77 GPRSErr gprsErr;
iva2k 0:e614f7875b60 78 gprsErr = m_pIf->connect(apn);
iva2k 0:e614f7875b60 79 if(gprsErr)
iva2k 0:e614f7875b60 80 return PPP_NETWORK;
iva2k 0:e614f7875b60 81
iva2k 0:e614f7875b60 82 DBG("\r\nPPPNetIf: If Connected.\r\n");
iva2k 0:e614f7875b60 83
iva2k 0:e614f7875b60 84 if( userId == NULL )
iva2k 0:e614f7875b60 85 pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL);
iva2k 0:e614f7875b60 86 else
iva2k 0:e614f7875b60 87 pppSetAuth(PPPAUTHTYPE_PAP, userId, password); //TODO: Allow CHAP as well
iva2k 0:e614f7875b60 88
iva2k 0:e614f7875b60 89 DBG("\r\nPPPNetIf: Set Auth.\r\n");
iva2k 0:e614f7875b60 90
iva2k 0:e614f7875b60 91 m_pIf->flushBuffer(); //Flush buffer before passing serial port to PPP
iva2k 0:e614f7875b60 92
iva2k 0:e614f7875b60 93 m_status = PPP_CONNECTING;
iva2k 0:e614f7875b60 94 int res = pppOverSerialOpen((void*)m_pIf, sPppCallback, (void*)this);
iva2k 0:e614f7875b60 95 if(res<0)
iva2k 0:e614f7875b60 96 {
iva2k 0:e614f7875b60 97 disconnect();
iva2k 0:e614f7875b60 98 return PPP_PROTOCOL;
iva2k 0:e614f7875b60 99 }
iva2k 0:e614f7875b60 100
iva2k 0:e614f7875b60 101 DBG("\r\nPPPNetIf: PPP Started with res = %d.\r\n", res);
iva2k 0:e614f7875b60 102
iva2k 0:e614f7875b60 103 m_fd = res;
iva2k 0:e614f7875b60 104 m_connected = true;
iva2k 0:e614f7875b60 105 Timer t;
iva2k 0:e614f7875b60 106 t.start();
iva2k 0:e614f7875b60 107 while( m_status == PPP_CONNECTING ) //Wait for callback
iva2k 0:e614f7875b60 108 {
iva2k 0:e614f7875b60 109 poll();
iva2k 0:e614f7875b60 110 if(t.read_ms()>PPP_TIMEOUT)
iva2k 0:e614f7875b60 111 {
iva2k 0:e614f7875b60 112 DBG("\r\nPPPNetIf: Timeout.\r\n");
iva2k 0:e614f7875b60 113 disconnect();
iva2k 0:e614f7875b60 114 return PPP_PROTOCOL;
iva2k 0:e614f7875b60 115 }
iva2k 0:e614f7875b60 116 }
iva2k 0:e614f7875b60 117
iva2k 0:e614f7875b60 118 DBG("\r\nPPPNetIf: Callback returned.\r\n");
iva2k 0:e614f7875b60 119
iva2k 0:e614f7875b60 120 if( m_status == PPP_DISCONNECTED )
iva2k 0:e614f7875b60 121 {
iva2k 0:e614f7875b60 122 disconnect();
iva2k 0:e614f7875b60 123 return PPP_PROTOCOL;
iva2k 0:e614f7875b60 124 }
iva2k 0:e614f7875b60 125
iva2k 0:e614f7875b60 126 return PPP_OK;
iva2k 0:e614f7875b60 127
iva2k 0:e614f7875b60 128 }
iva2k 0:e614f7875b60 129
iva2k 0:e614f7875b60 130 PPPErr PPPNetIf::ATConnect(const char* number) //Connect using a "classic" voice modem or GSM
iva2k 0:e614f7875b60 131 {
iva2k 0:e614f7875b60 132 //TODO: IMPL
iva2k 0:e614f7875b60 133 return PPP_MODEM;
iva2k 0:e614f7875b60 134 }
iva2k 0:e614f7875b60 135
iva2k 0:e614f7875b60 136 PPPErr PPPNetIf::disconnect()
iva2k 0:e614f7875b60 137 {
iva2k 0:e614f7875b60 138 pppClose(m_fd); //0 if ok, else should gen a WARN
iva2k 0:e614f7875b60 139 m_connected = false;
iva2k 0:e614f7875b60 140
iva2k 0:e614f7875b60 141 m_pIf->flushBuffer();
iva2k 0:e614f7875b60 142 m_pIf->printf("+++");
iva2k 0:e614f7875b60 143 wait(.1);
iva2k 0:e614f7875b60 144 m_pIf->flushBuffer();
iva2k 0:e614f7875b60 145
iva2k 0:e614f7875b60 146 GPRSErr gprsErr;
iva2k 0:e614f7875b60 147 gprsErr = m_pIf->disconnect();
iva2k 0:e614f7875b60 148 if(gprsErr)
iva2k 0:e614f7875b60 149 return PPP_NETWORK;
iva2k 0:e614f7875b60 150
iva2k 0:e614f7875b60 151 return PPP_OK;
iva2k 0:e614f7875b60 152 }
iva2k 0:e614f7875b60 153
iva2k 0:e614f7875b60 154 #if 0
iva2k 0:e614f7875b60 155 PPPErr PPPNetIf::close()
iva2k 0:e614f7875b60 156 {
iva2k 0:e614f7875b60 157 GPRSErr err = m_pIf->close();
iva2k 0:e614f7875b60 158 if(err)
iva2k 0:e614f7875b60 159 return PPP_MODEM;
iva2k 0:e614f7875b60 160 m_open = false;
iva2k 0:e614f7875b60 161 return PPP_OK;
iva2k 0:e614f7875b60 162 }
iva2k 0:e614f7875b60 163 #endif
iva2k 0:e614f7875b60 164
iva2k 0:e614f7875b60 165
iva2k 0:e614f7875b60 166 #if 0
iva2k 0:e614f7875b60 167 //We have to use :
iva2k 0:e614f7875b60 168
iva2k 0:e614f7875b60 169 /** Pass received raw characters to PPPoS to be decoded. This function is
iva2k 0:e614f7875b60 170 * thread-safe and can be called from a dedicated RX-thread or from a main-loop.
iva2k 0:e614f7875b60 171 *
iva2k 0:e614f7875b60 172 * @param pd PPP descriptor index, returned by pppOpen()
iva2k 0:e614f7875b60 173 * @param data received data
iva2k 0:e614f7875b60 174 * @param len length of received data
iva2k 0:e614f7875b60 175 */
iva2k 0:e614f7875b60 176 void
iva2k 0:e614f7875b60 177 pppos_input(int pd, u_char* data, int len)
iva2k 0:e614f7875b60 178 {
iva2k 0:e614f7875b60 179 pppInProc(&pppControl[pd].rx, data, len);
iva2k 0:e614f7875b60 180 }
iva2k 0:e614f7875b60 181 #endif
iva2k 0:e614f7875b60 182
iva2k 0:e614f7875b60 183 void PPPNetIf::poll()
iva2k 0:e614f7875b60 184 {
iva2k 0:e614f7875b60 185 if(!m_connected)
iva2k 0:e614f7875b60 186 return;
iva2k 0:e614f7875b60 187 LwipNetIf::poll();
iva2k 0:e614f7875b60 188 //static u8_t buf[128];
iva2k 0:e614f7875b60 189 int len = sio_tryread((sio_fd_t) m_pIf, m_buf, BUF_SIZE);
iva2k 0:e614f7875b60 190 if(len > 0)
iva2k 0:e614f7875b60 191 pppos_input(m_fd, m_buf, len);
iva2k 0:e614f7875b60 192 }
iva2k 0:e614f7875b60 193
iva2k 0:e614f7875b60 194 //Link Callback
iva2k 0:e614f7875b60 195 void PPPNetIf::pppCallback(int errCode, void *arg)
iva2k 0:e614f7875b60 196 {
iva2k 0:e614f7875b60 197 //DBG("\r\nPPPNetIf: Callback errCode = %d.\r\n", errCode);
iva2k 0:e614f7875b60 198 switch ( errCode )
iva2k 0:e614f7875b60 199 {
iva2k 0:e614f7875b60 200 //No error
iva2k 0:e614f7875b60 201 case PPPERR_NONE:
iva2k 0:e614f7875b60 202 m_status = PPP_CONNECTED;
iva2k 0:e614f7875b60 203 break;
iva2k 0:e614f7875b60 204 default:
iva2k 0:e614f7875b60 205 //Disconnected
iva2k 0:e614f7875b60 206 m_status = PPP_DISCONNECTED;
iva2k 0:e614f7875b60 207 break;
iva2k 0:e614f7875b60 208 }
iva2k 0:e614f7875b60 209 }
iva2k 0:e614f7875b60 210
iva2k 0:e614f7875b60 211 #endif