Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface mbed-rtos mbed tinydtls
Fork of tinydtls_test_ethernet by
main.cpp
- Committer:
- ashleymills
- Date:
- 2013-10-11
- Revision:
- 3:0caeed7fd9f0
- Parent:
- 2:21019cad4c93
- Child:
- 4:4d466a913c11
File content as of revision 3:0caeed7fd9f0:
#define __DEBUG__ 4
#ifndef __MODULE__
#define __MODULE__ "main.cpp"
#endif
#include "mbed.h"
#include "rtos.h"
#include "bsd_socket.h"
#include <dtls.h>
#include "global.h"
#include "debug.h"
#include "errno.h"
#include "dbg.h"
#include "EthernetInterface.h"
DigitalOut myled(LED1);
void fail(int code) {
while(1) {
myled = !myled;
Thread::wait(100);
}
}
/* This function is the "key store" for tinyDTLS. It is called to
* retrieve a key for the given identiy within this particular
* session. */
int
get_key(struct dtls_context_t *ctx,
const session_t *session,
const unsigned char *id, size_t id_len,
const dtls_key_t **result) {
DBG("Entered get_key");
static const dtls_key_t psk = {
.type = DTLS_KEY_PSK,
.key.psk.id = (unsigned char *)"Client_identity",
.key.psk.id_length = 15,
.key.psk.key = (unsigned char *)"secretPSK",
.key.psk.key_length = 9
};
*result = &psk;
return 0;
}
#define APN_GDSP
//#define APN_CONTRACT
#ifdef APN_GDSP
#define APN "ppinternetd.gdsp"
#define APN_USERNAME ""
#define APN_PASSWORD ""
#endif
#ifdef APN_CONTRACT
#define APN "internet"
#define APN_USERNAME "web"
#define APN_PASSWORD "web"
#endif
sockaddr_in bindAddr,serverAddress;
bool connectToSocketUDP(char *ipAddress, int port, int *sockfd) {
*sockfd = -1;
// create the socket
if((*sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) {
DBG("Error opening socket");
return false;
}
socklen_t sockAddrInLen = sizeof(struct sockaddr_in);
// bind socket
memset(&bindAddr, 0x00, sockAddrInLen);
bindAddr.sin_family = AF_INET; // IP family
bindAddr.sin_port = htons(port);
bindAddr.sin_addr.s_addr = IPADDR_ANY; // 32 bit IP representation
// call bind
if(bind(*sockfd,(const struct sockaddr *)&bindAddr,sockAddrInLen)!=0) {
DBG("Error binding socket");
perror(NULL);
}
INFO("UDP socket created and bound to: %s:%d",inet_ntoa(bindAddr.sin_addr),ntohs(bindAddr.sin_port));
// create the socket address
memset(&serverAddress, 0x00, sizeof(struct sockaddr_in));
serverAddress.sin_addr.s_addr = inet_addr(ipAddress);
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
// do socket connect
//LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port));
if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) {
shutdown(*sockfd,SHUT_RDWR);
close(*sockfd);
DBG("Could not connect");
return false;
}
return true;
}
int read_from_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) {
DBG("read_from_peer called");
size_t i;
for (i = 0; i < len; i++)
printf("%c", data[i]);
return 0;
}
int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) {
DBG("send_to_peer called");
int fd = *(int *)dtls_get_app_data(ctx);
return sendto(fd, data, len, MSG_DONTWAIT,
&session->addr.sa, session->size);
}
int
dtls_handle_read(struct dtls_context_t *ctx) {
DBG("dtls_handle_read called");
int fd;
session_t session;
#define MAX_READ_BUF 512
static uint8 buf[MAX_READ_BUF];
int len;
fd = *(int *)dtls_get_app_data(ctx);
/*
if(!fd) {
DBG("FD NULL");
return -1;
}*/
memset(&session, 0x00, sizeof(session_t));
DBG("BEFORE: ");
for(uint8_t i=0; i<sizeof(session_t); i++) {
DBGX("%x ",((uint8_t*)&session)[i]);
}
DBGX("\r\n");
session.size = sizeof(sockaddr_in);
uint32_t bullshit = sizeof(sockaddr_in);
len = recvfrom(fd, buf, MAX_READ_BUF, 0,
&session.addr.sa, &bullshit);
//((uint8_t*)&session)[4] = 0x00;
//session.addr.sin.sin_family = AF_INET;
DBG("AFTER: %d",bullshit);
for(uint8_t i=0; i<sizeof(session_t); i++) {
DBGX("%x ",((uint8_t*)&session)[i]);
}
DBGX("\r\n");
short x = session.addr.sin.sin_family;
if(session.addr.sin.sin_family==AF_INET) {
DBG("AF_INET alright");
}
DBG("%x %x",((uint8_t*)x)[0],((uint8_t*)x)[1]);
if (len < 0) {
DBG("Got nothing from read");
perror("recvfrom");
return -1;
} else {
#ifndef NDEBUG
unsigned char addrbuf[72];
dsrv_print_addr(&session, addrbuf, sizeof(addrbuf));
DBG("got %d bytes from %s\n", len, (char *)addrbuf);
dump((unsigned char *)&session, sizeof(session_t));
DBGX("\r\n");
dump(buf, len);
DBGX("\r\n");
#endif
}
return dtls_handle_message(ctx, &session, buf, len);
}
static dtls_handler_t cb = {
.write = send_to_peer,
.read = read_from_peer,
.event = NULL,
.get_key = get_key
};
int main() {
DBG_INIT();
DBG_SET_SPEED(115200);
DBG_SET_NEWLINE("\r\n");
DBG("Tiny DTLS test");
// DTLS context struct
dtls_context_t *dtls_context = NULL;
int ret = 0;
fd_set rfds, wfds;
struct timeval timeout;
session_t dst;
// structure for getting address of incoming packets
sockaddr_in fromAddr;
socklen_t fromAddrLen = sizeof(struct sockaddr_in);
memset(&fromAddr,0x00,fromAddrLen);
// connect to cellular network
/*
VodafoneUSBModem modem;
modem.connect(APN,APN_USERNAME,APN_PASSWORD);
*/
EthernetInterface modem;
DBG("Connecting to network interface");
modem.init();
if(modem.connect(10000)) {
DBG("Error initialising ethernet interface");
}
DBG("DONE.");
dtls_init();
dtls_set_log_level(LOG_DEBUG);
// setup socket to remote server
int sockfd = NULL;
if(!connectToSocketUDP("109.74.199.96", 4433, &sockfd)) {
//if(!connectToSocketUDP("192.168.1.99", 4433, &sockfd)) {
DBG("Error connecting to socket");
fail(1);
}
DBG("\"Connected\" to UDP socket, sockfd: %d",sockfd);
/*
int on = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) {
dsrv_log(LOG_ALERT, "setsockopt SO_REUSEADDR: %s\n", strerror(errno));
}*/
// tinydtls stuff
// destination address is stored in a session type
memset(&dst, 0x00, sizeof(session_t));
dst.size = sizeof(sockaddr_in);
DBG("starting copy at offset: %d",(int)&dst.addr-(int)&dst);
serverAddress.sin_len = dst.size;
memcpy(&dst.addr, &serverAddress, dst.size);
//dst.addr.sin.sin_port = htons(4433);
// dtls init must always be called for memory allocation
// setup DTLS context
DBG("Creating DTLS context");
dtls_context = dtls_new_context(&sockfd);
if(!dtls_context) {
DBG("Cannot create context");
fail(3);
}
DBG("DTLS context created");
// forced to use this call back system
dtls_set_handler(dtls_context, &cb);
DBG("Issuing dtls_connect");
ret = dtls_connect(dtls_context, &dst);
if(ret<0) {
DBG("Error in dtls_connect: %d",ret);
modem.disconnect();
fail(4);
}
if(ret==0) {
DBG("Channel already exists");
modem.disconnect();
fail(5);
}
DBG("dtls_connect successfull");
while (1) {
// setup file descriptor lists for select
FD_ZERO(&rfds);
FD_ZERO(&wfds);
//FD_SET(fileno(stdin), &rfds);
FD_SET(sockfd, &rfds);
// FD_SET(sockfd, &wfds);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int result = select(sockfd+1, &rfds, &wfds, 0, &timeout);
if(result < 0) { // error
if (errno != EINTR)
perror("select");
} else if (result == 0) {
// timeout
} else {
// OK
// check which file descriptor had an event
if(FD_ISSET(sockfd, &wfds)) {
// FIXME (from tinydtls)
} else if (FD_ISSET(sockfd, &rfds))
if(dtls_handle_read(dtls_context)<0) {
modem.disconnect();
fail(6);
}
}
//else if (FD_ISSET(fileno(stdin), &rfds))
//handle_stdin();
//}
//if(len) {
// try_send(dtls_context, &dst);
//}
}
}
