Pages: [1] 2 3   Go Down
Author Topic: Email attachments from arduino as an SMTP client  (Read 8968 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello All,

I tried searching the best keywords before posting here. I apologize if I am asking something that is obvious. I am aware of the fact that it is possible to send emails to the SMTP server using the arduino ethernet shield. I want to send picture attachments along with the mail. I am aware of the fact that it is possible to send attachments with some encoding inside the mail server. I would like to know whether there is any documentation of this being done using the arduino? I would be happy if some links are shared.

Thanks,
Sai
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50883
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am aware of the fact that it is possible to send attachments with some encoding inside the mail server. I would like to know whether there is any documentation of this being done using the arduino?
It is exactly the same as sending the attachment from the PC. Except sssslllloooowwwweeeerrrr. Much sssslllloooowwwweeeerrrr.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is it going to take for ever to transfer a 50KB picture?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50883
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is it going to take for ever to transfer a 50KB picture?
You can do the math. A 50,000 byte file is 400,000 bits. A 115200 baud rate means that 115200 bits per second get sent. Of those, 8 out of 10 are payload. 400,000 bits/8 = 50,000 packets. 11,500 packets per second will require about 5 seconds to send.

Your baud rate may be different, so the file might take longer to transfer.

The more important question is where in the Arduino's 2KB of SRAM are you planning on storing a 50KB picture?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oh I had plans of storing it in the SD card shield. Am I building forts in the air here? I thought 5 seconds is not bad...
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50883
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Where is/are the picture(s) coming from? Getting the data from the SD card will take time. The data will not be being sent while it is being read. So, you need to add the time needed to read the data from the card to the time needed to send the data to get the total time required to read and send a picture.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for enlightening me about the read and write problem. I did not consider it.

I was planning to take pictures using the camera:

http://www.sparkfun.com/products/10061

From what I read, the minimum file size of a captured frame is 3KB to 9KB. Hence If I store this image in SD card, I thought I could access it using an ethernet shield.

Sai
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know of any Arduino code to do it, but the first thing you'll need to find is an encoder to take whatever format the picture is in, ensure it turns up as a JPEG, PNG, or other file format, then encode that file for transmission by email. A common encoding mechanism is Base 64.

The Internet RFC that covers sending SMTP messages with MIME attachments is RFC 3030 - SMTP Service Extensions for Transmission of Large and Binary MIME Messages.

You could trawl through that one and try to interpret it yourself. Alternately you could send an email with an image attachment using your normal mail client and packet-sniff the exchange with the non-SSL mail server. Being able to replay that message would be an ideal starting point. You can "cheat" and simply take the encoded image data, store that on the SD Card, and write your code to assemble the SMTP message using the pre-encoded image. The next step would be writing the code to take the original image and end up with the encoded version.

Encoding files is not as scary as it sounds. Base64 encoding as defined in RFC 4648 is actually quite simple.

I would suggest the following steps:
  • Write a function that can send a simple email containing "hello world"
  • Write a function that will take a given Base 64 encoded file and wrap it with the appropriate SMTP & MIME leaders/trailers (i.e.: 'your' side of the SMTP conversation) as a script in a third file
  • Now simply play the script to the SMTP server, replacing "hello world" with the content of your script
  • Finally, write a function to take a given file on the SD card and convert it to Base 64 in a second file, reading a chunk, converting it and writing that chunk to the SD card (you'll want to do this in the smallest sized chunks you possibly can)

This will not handle errors gracefully, but handling SMTP errors gracefully is usually a matter of disconnecting and forgetting the transaction  smiley-twist

I guesstimate that a brain-dead implementation of the above will take somewhere in the order of a minute to send a 10kB image, most of which will be transferring data back and forth between the Arduino and the SD Card. A smarter implementation which can generate the SMTP conversation and do Base64 encoding on the fly should manage to send the entire message in a few seconds (limited by how fast you can read the data off the SD Card).

But baby steps. Remember Knuth:
  • First, make it work
  • Then, make it work right
  • Only then, make it work fast

In my brief flirtation with Bing and Google just now, I couldn't find any pointers to a Base64 library for Arduino. If anyone can find one, please mention it in this thread, 'cos I want to do Base64 encoding too smiley

If no such beast exists, that will probably be my homework for the weekend.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks.. This suggestion was valuable
Logged

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 149
LED
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I haven't tried sending an attachment, but sending plain text is pretty straightforward.

My problem was that I was trying to use a GMail account, and it needs TLS, something Arduino can't. But hopefully I found that Yahoo Mail doesn't need cipher.

Function would be something similar to:
Code:
// Hello World! Example: mail from foo@yahoo.com to bar@fakemail.com
client.connect("smtp.mail.yahoo.com",25);
client.print("HELO\n");
client.print("AUTH PLAIN\n");
client.print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n");  // x: base64 encoded login: \0foo@yahoo.com\0password
client.print("MAIL FROM:<foo@yahoo.com>\n");
client.print("RCPT TO:<bar@fakemail.com>\n");
client.print("DATA\n");
client.print("From: \"Foo\" <foo@yahoo.com>\r\n");
client.print("To: bar@fakemail.com>\r\n");
client.print("Subject: Buy Cialis\r\n");  // xD
client.print("\r\n");
client.print("Hello World!\r\n");  // Lines of text
// ......................................
client.print(".\r\n");
client.print("quit\n");
client.stop()
« Last Edit: July 27, 2011, 07:10:54 pm by Razorblade » Logged

Arduino Uno (R2fix) / Duemilanove (328p)
Ethernet Shield SD (v5)

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sending photo attachments is not a good task for the Arduino.  The ATmega328 is a microcontroller not a microprocessor.  Encoding, attaching, and sending a 50kb file through the poor little ATmega328 probably isn't worth the trouble.  There are a lot of limitations you'll have to solve with very creative solutions.

Now, if you are trying to do this under the category of "Let's see if it can be done" that is a different story.  If you are trying to accomplish any other goal (like build a system of automated webcams) the Arduino isn't a good choice.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My main objective is to transfer pictures from the JPEG cam that I posted above and I wanted to do it via ethernet shield/ arduino black widow shield. I am looking into best methods to do this.

Now that I posted here, I am able to gauge the possibilities before I hit a dead end. From what I read, the camera that I posted in my previous thread generates images from 3KB to 9KB. I do not want my arduino to be tethered to a computer via USB.

Will something like make sense for a picture transfer?

http://mightyohm.com/blog/2008/10/building-a-wifi-radio-part-1-introduction/

He has installed Linux inside an Asus router. Will hosting a mail client inside the router be a more sensible solution?
Logged

Atlanta, GA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

some cam's already have email and ftp build-in like the Trendnet TV-IP110 (cheap as in like $49)

but your issue with that model and google is ssl - there might be other cams that support ssl.

You could also look into plug computers or routers that support open source firmware (I use a reflashed unslung nslu2) then you can use bash, c or php to do what ever you want.

I looked at trying to reflash the cams but way less info and way over my head to try and be the first to do it - when compared to plug/router/nas reflashing there's a ton of info for those devices.




Logged

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 149
LED
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Am I invisible? smiley-red

Sending photo attachments is not a good task for the Arduino.  The ATmega328 is a microcontroller not a microprocessor.  Encoding, attaching, and sending a 50kb file through the poor little ATmega328 probably isn't worth the trouble.  There are a lot of limitations you'll have to solve with very creative solutions.
Pardon? What is the trouble? What limitations?

This would be how to base64 encode & send to the SMTP server a file named picture from a SD:
Code:
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void encodeblock(unsigned char in[3],unsigned char out[4],int len) {
  out[0]=cb64[in[0]>>2]; out[1]=cb64[((in[0]&0x03)<<4)|((in[1]&0xF0)>>4)];
  out[2]=(unsigned char) (len>1 ? cb64[((in[1]&0x0F)<<2)|((in[2]&0xC0)>>6)] : '=');
  out[3]=(unsigned char) (len>2 ? cb64[in[2]&0x3F] : '=');
}
void encode() {
  unsigned char in[3],out[4]; int i,len,blocksout=0;
  while (picture.available()!=0) {
    len=0;
    for (i=0;i<3;i++) { in[i]=(unsigned char) picture.read(); if (picture.available()!=0) len++; else in[i]=0; }
    if (len) { encodeblock(in,out,len); for(i=0;i<4;i++) client.write(out[i]); blocksout++; }
    if (blocksout>=19||picture.available()==0) { if (blocksout) client.print("\r\n");  blocksout=0; }
  }
}
Logged

Arduino Uno (R2fix) / Duemilanove (328p)
Ethernet Shield SD (v5)

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Interesting problem. Obviously, the hardest part is to build the SMTP client state machine that implements something like section 4.2 in RFC 3030 (see link in reply by ManicDee). Assuming your SMTP server supports chunking, then all you have to do is the following:

1) Get the binary data of the image file as a stream of octets (bytes)
2) Invoke the state machine and follow the protocol (plus whatever cleartext auth needed) up until the BDAT part
3) Issue a BDAT for the size of the binary data (or send them in chunks)
4) Blast the binary data across the wire.
5) Issue a BDAT 0 LAST
6) Wait for confirmation of all data chunks, issue QUIT and close the connection.

You should be able to find C-based SMTP client code in the open-source realm and adapt it for the Arduino. In any case, sounds like quite a bit of work. Also, I would imagine it would be very, very hard to build an SSL stack on the Arduino.

Just my 2 cents' worth from a backseat commentator.  :-)
Logged

Pages: [1] 2 3   Go Up
Jump to: