Ethernet test for tinydtls-0.5.0
Dependencies: EthernetInterface mbed-rtos mbed tinydtls
Fork of tinydtls_test_ethernet by
main.cpp
- Committer:
- ashleymills
- Date:
- 2013-10-18
- Revision:
- 4:4d466a913c11
- Parent:
- 3:0caeed7fd9f0
File content as of revision 4:4d466a913c11:
#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); } } static const unsigned char ecdsa_priv_key[] = { 0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14, 0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14, 0x89, 0x6A, 0x33, 0xBB, 0xAD, 0x72, 0x94, 0xCA, 0x40, 0x14, 0x55, 0xA1, 0x94, 0xA9, 0x49, 0xFA}; static const unsigned char ecdsa_pub_key_x[] = { 0x36, 0xDF, 0xE2, 0xC6, 0xF9, 0xF2, 0xED, 0x29, 0xDA, 0x0A, 0x9A, 0x8F, 0x62, 0x68, 0x4E, 0x91, 0x63, 0x75, 0xBA, 0x10, 0x30, 0x0C, 0x28, 0xC5, 0xE4, 0x7C, 0xFB, 0xF2, 0x5F, 0xA5, 0x8F, 0x52}; static const unsigned char ecdsa_pub_key_y[] = { 0x71, 0xA0, 0xD4, 0xFC, 0xDE, 0x1A, 0xB8, 0x78, 0x5A, 0x3C, 0x78, 0x69, 0x35, 0xA7, 0xCF, 0xAB, 0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B, 0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29}; static const dtls_psk_key_t client_psk = { .id = (unsigned char *)"Client_identity", .id_length = 15, .key = (unsigned char *)"secretPSK", .key_length = 9 }; /* 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_psk_key(struct dtls_context_t *ctx, const session_t *session, const unsigned char *id, size_t id_len, const dtls_psk_key_t **result) { DBG("id: %d, len: %d",id,id_len); *result = &client_psk; return 0; } int get_ecdsa_key(struct dtls_context_t *ctx, const session_t *session, const dtls_ecdsa_key_t **result) { static const dtls_ecdsa_key_t ecdsa_key = { .curve = DTLS_ECDH_CURVE_SECP256R1, .priv_key = ecdsa_priv_key, .pub_key_x = ecdsa_pub_key_x, .pub_key_y = ecdsa_pub_key_y }; *result = &ecdsa_key; return 0; } int verify_ecdsa_key(struct dtls_context_t *ctx, const session_t *session, const unsigned char *other_pub_x, const unsigned char *other_pub_y, size_t key_size) { 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: %d",len); 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: %d",len); 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, 0, sizeof(session_t)); session.size = sizeof(session.addr); len = recvfrom(fd, buf, MAX_READ_BUF, 0, &session.addr.sa, &session.size); 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); } int gDTLSConnected = 0; // callback called on tinydtls events (currently only ever called for DTLS_EVENT_CONNECTED) int event_handler( struct dtls_context_t *ctx, session_t *session, dtls_alert_level_t level, unsigned short code) { DBG("DTLS SESSION SETUP COMPLETE"); gDTLSConnected = 1; return 0; } static dtls_handler_t cb = { .write = send_to_peer, .read = read_from_peer, .event = event_handler, .get_psk_key = get_psk_key, .get_ecdsa_key = NULL,// get_ecdsa_key, .verify_ecdsa_key = NULL//verify_ecdsa_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"); int counter = 0; char outBuf[64]; 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 = 15; timeout.tv_usec = 0; DBG("Waiting for data"); int result = select(sockfd+1, &rfds, &wfds, 0, &timeout); if(result < 0) { // error if (errno != EINTR) perror("select"); } else if (result == 0) { // timeout if(gDTLSConnected) { DBG("Sending data"); sprintf(outBuf,"This is a pointless test message: %d\r\n",counter++); dtls_write(dtls_context, &dst, (uint8 *)outBuf, strlen(outBuf)); //try_send(dtls_context, &dst); } } 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); //} } }