"Tauno Voipio" <tauno.voipio@INVALIDiki.fi> wrote
> Don wrote:
(sigh) Actually, *you* wrote:
> >>the embedded device is a server and the terminal is a client.
To which I replied:
> > Since when are embedded devices "servers"? There is nothing
> > in the nature of an embedded device that makes it a server *or*
> > a client.
>
> The common reason for using TCP/IP in an embedded device
> is to use a WWW browser as the control panel for the device.
>
> This has to be a server.
You're stuck thinking *in* the box! I can (and do!) design boxes
that are configured via web interfaces yet are *pure* clients -- by
storing the configuration *elsewhere* and letting my client
SIMPLY RETRIEVE it!
> Please provide an example of an embedded device which
> acts as a client.
I provided an example in the previous post, to which my comments
below will refer.
> Yes, I know that TCP is symmetrical as soon as the
> connection is made. For the current discussion, a
> client is the host initiating the connection and a
> server is the host responding to the initiation. This
> is the relevant point for the visibility of the
> IP addresses: to initiate the connection, the IP
> of the responding host has to be known.
First, the IP address needs to be known (*)
REGARDLESS of whether a human user needs
it in order to type a URL into their browser.
The *device* nees to know it in order to carry on the
"conversation". So, even devices that don't require
any "configuration" *still* need to know their assigned
IP. The issues raised by the OP ertain *regardless*
of whether or not the IP needs to be (humanly) visible.
So, address discovery methods (as brought up by the
OP) are important.
[* there are games you can play on small, private
networks where only MAC addresses are used but
that's *too* far "outside the box" for this discussion]
Second, *you* are assuming that the "user" is the
"client" and the embedded device is the server. That's
an *assumption* and not a *requirement*!
I've been redesigning the appliances *here* as pure
clients -- in a manner similar to the device described
in my previous post. Specifically:
- all are clients
- none store persistent state (or configuration) internally
- all are *extremely* simple to design and dirt cheap to build
- all are maintained remotely
- none are reliant on particular hardware for communication
(i.e. I could run SLIP over a length of CAT1)
Without knowledge of particular applications/markets, it's
hard to come up with specific criteria. There's no way to
know if the devices in question are costly or dirt cheap.
But, *my* reasoning tries to accommodate the sorts of
designs that I have to produce. In no particular order:
- By NOT storing state in the device(s), there is less memory
required. And, most importantly, no *batteries* to maintain!
(Sure, you may get several years out of a lithium cell... but tell
a customer that every 5 years they have to replace all of the
batteries in every room of their HOTEL and you'll find this
"hidden cost" exceeds the purchase price of your device!)
Also, removing the battery requirement make the device hardier
in terms of the environmental extremes it can safely/practically
be exposed to. For example, the garage at my residence sees
temperatures in excess of 140F (60C?) daily. Other places
where I have resided saw outdoor temps below -20F. Locating
a battery in either extreme means short life for the battery!
(Or, special instructions telling the user he *can't* locate the
device in those extremes).
Of course, the use of a battery is suggestive of some nonvolatile
*operation* (e.g., keeping track of time of day). Static *data*
can be stored in FLASH -- but then you are required to pick
a device that *has* flash onboard (or add something externally).
Regardless, if you have state preserved onboard, you also need
to be able to verify that it hasn't been corrupted. *AND*, if it
*has* been corrupted, how do you get an *update*? What do
you do *until* you have that update? How do you tell the user
"please reconnect your browser to me and tell me what I am
supposed to be doing..."?
How much error in a ToD clock is "acceptable"? Do you come up
with different recovery strategies for different devices based on
how critical their stored data is for their continued operation?
- Placing the user interface *in* the embedded device significantly
increases the complexity of that device. Increased complexity
means greater propensiy for bugs. Embedded devices don't
readily lend themselves to software upgrades (unless you
specifically *add* facilities and mechanisms to do so!)
How do you tell the user that he has made an error in specifying
a partiular parameter? Is there any "on-line help" available to him?
What NLS support do you include in your served pages? Or,
do you just tie it to a particular locale? E.g., is today 11/03/05?
Or, 20051103? Is it a 24hour clock or 12hour? etc.
Do you enforce any mechanisms to regulate access to the configuration
"pages"? Perhaps a *password*? Is the user's "session" limited to
a single "page"? How do you track a valid session (store a cookie
on the user's browser)? What if the user fails to explicitly terminate
that "session"?
How do you deal with multiple clients wanting to access the
HTTP server concurrently? How do you resolve the readers/writers
issue? How do you deal with multiple clients wanting to *update*
the configuration concurrently (perhaps one is accessing
configuration page 1 while nother is accessing page 3)? If you enforce
a mutex on the resource, how do you recover from a user failing
to release that resource? (remember, the "reset" button on the
device may be located a few thousand miles from the user!)
- The suggested approach of embedding the web server in the device
means you need to have an HTTP server, some sort of "file system"
(even if it is a crude collection of char *[]'s referencing the text
of the embedded "pages"), some way of parsing the forms data
submitted, etc.
Invariably, there will be restrictions on the HTML (et al.) features
that can be embedded in those pages. Most due to resource
requirements. Some due to software support (e.g., serving up
streaming audio).
Do you track when changes are made to the configuration data
(web pages)? Is any sort of audit trail required? Where will
*that* reside? How will it be accessed for audits?? (what if your
device is a security system for managing access to commercial
real estate -- surely you want to know who tampered with
the access codes, etc.)
- But, embedding a web server implicitly requires support for a full
TCP/IP stack! This is more expensive in terms of resources.
TCP *connections* consume more resources. Since it is a
connection-oriented protocol, there will be *some* limit on the
number of connections it can support (how many sockets?).
And timers to release sockets from dropped connections, etc.
Lot more complexity that has to be managed just to accommodate
a server *in* the device. Since resources are never (?) as plentiful
in an embedded device as a desktop device, you end up making
lots of compromises in the design and implementation. And, many
of those cmpromises are directly visible to the user -- since this
is the user interface that we are discussing! :>
In short, you end up putting a feature-poor interface because a
full-featured interface increase the cost/complexity significantly.
OTOH, consider the approach I have taken:
Devices are pure clients. They rely on server(s) to provide
*services* that they need to perform their respective functions.
Again, they *RELY* on server(s). Just like your device
*RELIES* on having power available. Or having functioning
memory. Or an RTC battery that isn't stale, etc. This is key! I can
now proceed with the design *knowing* that the services
I need are available (with special consideration for those few
cases where a resource failure could be costly/invonvenient).
Sure, you can claim that you expect your battery backed ToD
clock to be accurate and *rely* on that. But, for you to
*ensure* that to be true, you must ensure the btteries are
replaced regularly, etc. For *me* to be able to rely on
services being available, all I need to do is dsign my server(s)
to be reliable (this is actually pretty easily accomplished).
This can be located in a nice, warm, dry, etc. place
(whereas a sprinkler system control box may be located
outside, and it may be RAINING when I need to change
the battery in it's onboard RTC!)
Since the device *knows* that its server(s) *are* always
available, there is no need for it to store any persistent
state -- RELY on a file server to store that state on
its behalf. And, rely on that server to *reliably* store
the state (instead of having to design that reliability
into the embedded device!)
Likewise, no need to maintain a non-volatile ToD clock.
Instead, *rely* on a time server to tell you what time it is.
No need to provide the user with a means for setting
the time on *this* embedded device... and for ensuring
that the time set on all of the other time-aware embedded
devices are all "in agreement" (ignoring, for the time being,
the possibility that you may actually need for those devices
to be *precisely* synchronized to sub-second resolution!)
Since the device doesn't have to serve web pages, there is
no need for an HTTP server, pseudo "file system", etc. The
*requirement* to support TCP is now gone. You can opt for
a simpler UDP stack. You can use connectionless protocols
thereby simplifying the code inside the embedded device.
Memory requirements can shrink *dramatically*! You can
now deal with ~512 byte packets instead of long datastreams.
And, by defining those packets cleverly, you can strip the
data you need from the packet *as* you receive it (so you
don't even need to store the whole packet and parse it
later).
Since you *know* you have these services available, you can
define the operation of an embedded device (e.g., my sprinkler
system described previously), for example, to be:
-power up
-broadcast BOOTPc request ("Who am I?") using UDP
-receive BOOTPs reply ("You are a.b.c.d/m; your
name servers are located at e.f.g.h and i.j.k.l; your
time server is located at TimeOfDay;your TFTP server is
BootstrapServer.MyPlace.com; your bootstrap code
is located in the file MyBootstrapCode located in directory
/firmware on that server; etc.")
- configure your IP address & netmask to a.b.c.d/m
- set your resolver library to use e.f.g.h and i.j.k.l
- resolve "BootstrapServer.MyPlace.com" using DNS
over UDP -- which *should* happen immediately since
you *know* these services are available! :>
- use the IP returned for BootstrapServer to issue TFTP
requests to that server for /firmware/MyBootstrapCode
- receive each packet from the TFTP server and build
your executable file (in RAM, FLASH, etc.) -- assuming
you actually *need* to perform this step (it gives you a
*free* mechanism for software updates! :>)
- resolve TimeOfDay to get the IP address of the NTP
server.
- contact the NTP server (over UDP) to get the current time
of day. This can be used to initialize a software-based RTC
which can be periodically reinitialized (every *minute*, hour,
day, etc.). Or, you could implement NTP on the embedded
device to synchronize the time more "gracefully". *Or* you
could just repeatedly ask "what time is it" and NEVER keep
track of the current time!
- fetch your configuration file (application specific) from
(yet another?) TFTP server and use it to configure your
application.
- run your application -- consulting servers as necessary to perform
those duties ("What time is it? Do I have to *do* anything at
*this* time? OK, I'll do it. Otherwise I'll go back and check
again...")
EXACTLY like the X Terminals (I guess they are NOT so
different from "embedded devices" after all, eh? :> )
Now, the user interface can reside in the *server*! The user
interfaces for *all* of these devices are just web pages (if
you opt for that sort of interface) served up by that *one*
web server. Server side scripts can parse the forms
submitted by the user and build the "configuration files"
used by the embedded device CLIENTS. The server
can have a much richer set of resources (than any of
the dumb, inexpensive, *plentiful* clients). It can provide
"on-line help", more extensive diagnostics, support for
different locales, etc. Instead of trying to put all this in
*each* embedded device (which makes them *all*
more complicated and expensive and, inevitably, causes
them all to be kludgy because you can't afford all of those
"niceties"), you put it in one place and let them all *share*
it.
It also makes development of that user interface easier
since you aren't recompiling code to embed your newest
char *[] of web pages, etc. And, the web pages for each
"Model 127 Widget" are guaranteed to be the same -- without
you having to remember to update them in each "unit".
There are lots of other "free fetures" that come with this
sort of approach:
For example, if you need to replace a defective device, you
simply replace the *device* -- no need to reconfigure it!
(the configuration resides on the server(s).
Everything on the server(s) can be BACKED UP...
how do you backup the configuration of *your*
sprinkler system, firewall, router, etc.? :>
Maintaining lots of devices *remotely* can be a lot
easier -- since some *other* server can talk to *your*
server and exchange status/configuration data/updates
to a centralized remote host.
Since the server(s) are "always available" (i.e. available
whenever the devices that depend on them require),
you can migrate portions of the application(s) into the
server (!). This can be used to "dumb down" the
"clients" (for example, keeping track of the date to
update the watering schedule for hot/dry months vs.
wet/cool ones; *or* to predict sunrise/sunset so that
the irrigation schedule can be updated to ensure watering
is done at night to minimize evaporative losses)
Or, the server's "smarts" can be used to add additionally
capabilities that span multiple devices. For example, knowing
(from the HVAC control system) that the "swamp cooler"
is in use *today* (based on temperature, humidity, etc.)
might allow you to modify the irrigation system's schedule
since the "bleed off" water from the swamp cooler is being
used to irrigate the rose bed (so DON'T run the "roses"
circuit in the irrigation system today!)
(sigh) Apologies for the long-winded description. :-(
It was intended to explain why an embedded device need
*not* be a "server". And, to show why this approach
can have significant merit -- especially as more and more
things become "aware" and more opportunities for
integration *among* those devices arise.
At least, it hopefully shows *one* way to think outside
the box :-/
--don