/* * Verifies that coap_parse() recognizes inclusion of too many options. */ static void test_nanocoap__server_option_count_overflow(void) { /* base pkt is a GET for /riot/value, which results in two options for the * path, but only 1 entry in the options array. * Size buf to accept an extra 2-byte option */ unsigned base_len = 17; uint8_t buf[17 + (2 * NANOCOAP_NOPTS_MAX)] = { 0x42, 0x01, 0xbe, 0x16, 0x35, 0x61, 0xb4, 0x72, 0x69, 0x6f, 0x74, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65 }; coap_pkt_t pkt; /* nonsense filler option that contains a single byte of data */ uint8_t fill_opt[] = { 0x11, 0x01 }; /* fill pkt with maximum options; should succeed */ int i = 0; for (; i < (2 * (NANOCOAP_NOPTS_MAX - 1)); i+=2) { memcpy(&buf[base_len+i], fill_opt, 2); } /* don't read final two bytes, where overflow option will be added later */ int res = coap_parse(&pkt, buf, sizeof(buf) - 2); TEST_ASSERT_EQUAL_INT(0, res); /* add option to overflow */ memcpy(&buf[base_len+i], fill_opt, 2); res = coap_parse(&pkt, buf, sizeof(buf)); TEST_ASSERT(res < 0); }
/* * Starts a blocking and never-returning loop dispatching CoAP requests. * * When using gnrc, make sure the calling thread has an initialized msg queue. */ void microcoap_server_loop(void) { static const sock_udp_ep_t local = { .family = AF_INET6, .port = COAP_SERVER_PORT }; sock_udp_ep_t remote; sock_udp_t sock; int rc = sock_udp_create(&sock, &local, NULL, 0); while (1) { DEBUG("Waiting for incoming UDP packet...\n"); rc = sock_udp_recv(&sock, (char *)_udp_buf, sizeof(_udp_buf), SOCK_NO_TIMEOUT, &remote); if (rc < 0) { DEBUG("Error in sock_udp_recv(). rc=%u\n", rc); continue; } size_t n = rc; coap_packet_t pkt; DEBUG("Received packet: "); coap_dump(_udp_buf, n, true); DEBUG("\n"); /* parse UDP packet to CoAP */ if (0 != (rc = coap_parse(&pkt, _udp_buf, n))) { DEBUG("Bad packet rc=%d\n", rc); } else { coap_packet_t rsppkt; DEBUG("content:\n"); coap_dumpPacket(&pkt); /* handle CoAP request */ coap_handle_req(&scratch_buf, &pkt, &rsppkt); /* build reply */ size_t rsplen = sizeof(_udp_buf); if ((rc = coap_build(_udp_buf, &rsplen, &rsppkt)) != 0) { DEBUG("coap_build failed rc=%d\n", rc); } else { DEBUG("Sending packet: "); coap_dump(_udp_buf, rsplen, true); DEBUG("\n"); DEBUG("content:\n"); coap_dumpPacket(&rsppkt); /* send reply via UDP */ rc = sock_udp_send(&sock, _udp_buf, rsplen, &remote); if (rc < 0) { DEBUG("Error sending CoAP reply via udp; %u\n", rc); } } } } }
/* * Validates encoded message ID byte order and put/get URI option. */ static void test_nanocoap__hdr(void) { uint8_t buf[_BUF_SIZE]; uint16_t msgid = 0xABCD; char path[] = "/test/abcd/efgh"; char loc_path[] = "/foo/bar"; unsigned char path_tmp[64] = {0}; uint8_t *pktpos = &buf[0]; pktpos += coap_build_hdr((coap_hdr_t *)pktpos, COAP_TYPE_CON, NULL, 0, COAP_METHOD_GET, msgid); pktpos += coap_opt_put_location_path(pktpos, 0, loc_path); pktpos += coap_opt_put_uri_path(pktpos, COAP_OPT_LOCATION_PATH, path); coap_pkt_t pkt; coap_parse(&pkt, &buf[0], pktpos - &buf[0]); TEST_ASSERT_EQUAL_INT(msgid, coap_get_id(&pkt)); int res = coap_get_uri_path(&pkt, path_tmp); TEST_ASSERT_EQUAL_INT(sizeof(path), res); TEST_ASSERT_EQUAL_STRING((char *)path, (char *)path_tmp); res = coap_get_location_path(&pkt, path_tmp, 64); TEST_ASSERT_EQUAL_INT(sizeof(loc_path), res); TEST_ASSERT_EQUAL_STRING((char *)loc_path, (char *)path_tmp); }
/* * Client GET response success case. Test parsing response. * Response for /time resource from libcoap example */ static void test_gcoap__client_get_resp(void) { uint8_t buf[GCOAP_PDU_BUF_SIZE]; coap_pkt_t pdu; int res; char exp_payload[] = "Oct 22 10:46:48"; uint8_t pdu_data[] = { 0x52, 0x45, 0xe6, 0x02, 0x9b, 0xce, 0xc0, 0x21, 0x01, 0xff, 0x4f, 0x63, 0x74, 0x20, 0x32, 0x32, 0x20, 0x31, 0x30, 0x3a, 0x34, 0x36, 0x3a, 0x34, 0x38 }; memcpy(buf, pdu_data, sizeof(pdu_data)); res = coap_parse(&pdu, &buf[0], sizeof(pdu_data)); TEST_ASSERT_EQUAL_INT(0, res); TEST_ASSERT_EQUAL_INT(COAP_CLASS_SUCCESS, coap_get_code_class(&pdu)); TEST_ASSERT_EQUAL_INT(GCOAP_TOKENLEN, coap_get_token_len(&pdu)); TEST_ASSERT_EQUAL_INT(4 + GCOAP_TOKENLEN, coap_get_total_hdr_len(&pdu)); TEST_ASSERT_EQUAL_INT(COAP_TYPE_NON, coap_get_type(&pdu)); TEST_ASSERT_EQUAL_INT(strlen(exp_payload), pdu.payload_len); for (size_t i = 0; i < strlen(exp_payload); i++) { TEST_ASSERT_EQUAL_INT(exp_payload[i], pdu.payload[i]); } }
/* Listen for an incoming CoAP message. */ static void _listen(sock_udp_t *sock) { coap_pkt_t pdu; uint8_t buf[GCOAP_PDU_BUF_SIZE]; sock_udp_ep_t remote; gcoap_request_memo_t *memo = NULL; uint8_t open_reqs = gcoap_op_state(); ssize_t res = sock_udp_recv(sock, buf, sizeof(buf), open_reqs > 0 ? GCOAP_RECV_TIMEOUT : SOCK_NO_TIMEOUT, &remote); if (res <= 0) { #if ENABLE_DEBUG if (res < 0 && res != -ETIMEDOUT) { DEBUG("gcoap: udp recv failure: %d\n", res); } #endif return; } res = coap_parse(&pdu, buf, res); if (res < 0) { DEBUG("gcoap: parse failure: %d\n", res); /* If a response, can't clear memo, but it will timeout later. */ return; } if (pdu.hdr->code == COAP_CODE_EMPTY) { DEBUG("gcoap: empty messages not handled yet\n"); return; /* incoming request */ } else if (coap_get_code_class(&pdu) == COAP_CLASS_REQ) { if (coap_get_type(&pdu) == COAP_TYPE_NON || coap_get_type(&pdu) == COAP_TYPE_CON) { size_t pdu_len = _handle_req(&pdu, buf, sizeof(buf), &remote); if (pdu_len > 0) { sock_udp_send(sock, buf, pdu_len, &remote); } } else { DEBUG("gcoap: illegal request type: %u\n", coap_get_type(&pdu)); return; } } /* incoming response */ else { _find_req_memo(&memo, &pdu, &remote); if (memo) { xtimer_remove(&memo->response_timer); memo->state = GCOAP_MEMO_RESP; memo->resp_handler(memo->state, &pdu, &remote); memo->state = GCOAP_MEMO_UNUSED; } } }
ssize_t nanocoap_request(coap_pkt_t *pkt, sock_udp_ep_t *local, sock_udp_ep_t *remote, size_t len) { ssize_t res; size_t pdu_len = (pkt->payload - (uint8_t *)pkt->hdr) + pkt->payload_len; uint8_t *buf = (uint8_t*)pkt->hdr; sock_udp_t sock; if (!remote->port) { remote->port = COAP_PORT; } res = sock_udp_create(&sock, local, remote, 0); if (res < 0) { return res; } /* TODO: timeout random between between ACK_TIMEOUT and (ACK_TIMEOUT * * ACK_RANDOM_FACTOR) */ uint32_t timeout = COAP_ACK_TIMEOUT * US_PER_SEC; unsigned tries_left = COAP_MAX_RETRANSMIT + 1; /* add 1 for initial transmit */ while (tries_left) { res = sock_udp_send(&sock, buf, pdu_len, NULL); if (res <= 0) { DEBUG("nanocoap: error sending coap request, %d\n", (int)res); break; } res = sock_udp_recv(&sock, buf, len, timeout, NULL); if (res <= 0) { if (res == -ETIMEDOUT) { DEBUG("nanocoap: timeout\n"); timeout *= 2; tries_left--; if (!tries_left) { DEBUG("nanocoap: maximum retries reached\n"); } continue; } DEBUG("nanocoap: error receiving coap response, %d\n", (int)res); break; } else { if (coap_parse(pkt, (uint8_t *)buf, res) < 0) { DEBUG("nanocoap: error parsing packet\n"); res = -EBADMSG; } break; } } sock_udp_close(&sock); return res; }
/* * Helper for server_get tests below. * GET request for nanocoap server example /riot/value resource. * Includes 2-byte token; confirmable. * Generated with libcoap. */ static int _read_riot_value_req_con(coap_pkt_t *pkt, uint8_t *buf) { uint8_t pkt_data[] = { 0x42, 0x01, 0xbe, 0x16, 0x35, 0x61, 0xb4, 0x72, 0x69, 0x6f, 0x74, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65 }; memcpy(buf, pkt_data, sizeof(pkt_data)); return coap_parse(pkt, buf, sizeof(pkt_data)); }
/* * Helper for server_get tests below. * Request from libcoap example for gcoap_cli /cli/stats resource * Include 2-byte token and Uri-Host option. */ static int _read_cli_stats_req(coap_pkt_t *pdu, uint8_t *buf) { uint8_t pdu_data[] = { 0x52, 0x01, 0x20, 0xb6, 0x35, 0x61, 0x3d, 0x10, 0x66, 0x65, 0x38, 0x30, 0x3a, 0x3a, 0x38, 0x63, 0x32, 0x3a, 0x31, 0x33, 0x66, 0x66, 0x3a, 0x66, 0x65, 0x63, 0x30, 0x3a, 0x35, 0x65, 0x31, 0x32, 0x25, 0x74, 0x61, 0x70, 0x30, 0x83, 0x63, 0x6c, 0x69, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73 }; memcpy(buf, pdu_data, sizeof(pdu_data)); return coap_parse(pdu, buf, sizeof(pdu_data)); }
static void test_nanocoap__server_option_count_overflow_check(void) { /* this test passes a forged CoAP packet containing 42 options (provided by * @nmeum in #10753, 42 is a random number which just needs to be higher * than NANOCOAP_NOPTS_MAX) to coap_parse(). The used coap_pkt_t is part * of a struct, followed by an array of 42 coap_option_t. The array is * cleared before the call to coap_parse(). If the overflow protection is * working, the array must still be clear after parsing the packet, and the * proper error code (-ENOMEM) is returned. Otherwise, the parsing wrote * past scratch.pkt, thus the array is not zeroed anymore. */ static uint8_t pkt_data[] = { 0x40, 0x01, 0x09, 0x26, 0x01, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17, 0x11, 0x17 }; /* ensure NANOCOAP_NOPTS_MAX is actually lower than 42 */ TEST_ASSERT(NANOCOAP_NOPTS_MAX < 42); struct { coap_pkt_t pkt; uint8_t guard_data[42 * sizeof(coap_optpos_t)]; } scratch; memset(&scratch, 0, sizeof(scratch)); int res = coap_parse(&scratch.pkt, pkt_data, sizeof(pkt_data)); /* check if any byte of the guard_data array is non-zero */ int dirty = 0; volatile uint8_t *pos = scratch.guard_data; for (size_t i = 0; i < sizeof(scratch.guard_data); i++) { if (*pos) { dirty = 1; break; } } TEST_ASSERT_EQUAL_INT(0, dirty); TEST_ASSERT_EQUAL_INT(-ENOMEM, res); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(coap_server_thread(struct pt *pt)) { PT_BEGIN(pt); uint16_t xt; uint16_t tmp; while(1) { PT_WAIT_UNTIL(pt,check_flag(new_packet,coap_server_flag)); if((buf[IP_PROTO_P]==IP_PROTO_UDP_V) && (buf[UDP_DST_PORT_H_P]==(COAPPORT>>8)) && (buf[UDP_DST_PORT_L_P]==(COAPPORT&0xff))) { /* UDP message length calculation */ xt = ((buf[UDP_LEN_H_P]<<8)+buf[UDP_LEN_L_P])-8; #if 1 if(coap_parse(&pkt,buf+UDP_DATA_P,xt) != 0) { dbg(PSTR("\r\n> Bad coap packet\r\n")); } else { coap_handle_req(&scratch_buf, &pkt, &rsppkt); xt = sizeof(response); coap_build(response, &xt, &rsppkt); make_udp_reply_from_request(buf,response,xt,COAPPORT); } #endif } clear_flag(new_packet,coap_server_flag); } PT_END(pt); }/*---------------------------------------------------------------------------*/
/* * Validates encoded message ID byte order and put/get URI option. */ static void test_nanocoap__hdr(void) { uint8_t buf[128]; uint16_t msgid = 0xABCD; char path[] = "/test/abcd/efgh"; unsigned char path_tmp[64] = {0}; uint8_t *pktpos = &buf[0]; pktpos += coap_build_hdr((coap_hdr_t *)pktpos, COAP_REQ, NULL, 0, COAP_METHOD_GET, msgid); pktpos += coap_put_option_uri(pktpos, 0, path, COAP_OPT_URI_PATH); coap_pkt_t pkt; coap_parse(&pkt, &buf[0], pktpos - &buf[0]); TEST_ASSERT_EQUAL_INT(msgid, coap_get_id(&pkt)); int res = coap_get_uri(&pkt, path_tmp); TEST_ASSERT_EQUAL_INT(sizeof(path), res); TEST_ASSERT_EQUAL_STRING((char *)path, (char *)path_tmp); }
void *microcoap_server(void *arg) { (void) arg; msg_init_queue(_coap_msg_q, Q_SZ); uint8_t laddr[16] = { 0 }; uint8_t raddr[16] = { 0 }; size_t raddr_len; uint16_t rport; conn_udp_t conn; int rc = conn_udp_create(&conn, laddr, sizeof(laddr), AF_INET6, COAP_SERVER_PORT); while (1) { if ((rc = conn_udp_recvfrom(&conn, (char *)udp_buf, sizeof(udp_buf), raddr, &raddr_len, &rport)) < 0) { continue; } coap_packet_t pkt; /* parse UDP packet to CoAP */ if (0 == (rc = coap_parse(&pkt, udp_buf, rc))) { coap_packet_t rsppkt; /* handle CoAP request */ coap_handle_req(&scratch_buf, &pkt, &rsppkt, false, false); /* build reply */ size_t rsplen = sizeof(udp_buf); if ((rc = coap_build(udp_buf, &rsplen, &rsppkt)) == 0) { /* send reply via UDP */ rc = conn_udp_sendto(udp_buf, rsplen, NULL, 0, raddr, raddr_len, AF_INET6, COAP_SERVER_PORT, rport); } } } /* never reached */ return NULL; }
int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize) { sock_udp_t sock; sock_udp_ep_t remote; if (!local->port) { local->port = COAP_PORT; } ssize_t res = sock_udp_create(&sock, local, NULL, 0); if (res != 0) { return -1; } while (1) { res = sock_udp_recv(&sock, buf, bufsize, -1, &remote); if (res < 0) { DEBUG("error receiving UDP packet %d\n", (int)res); } else if (res > 0) { coap_pkt_t pkt; if (coap_parse(&pkt, (uint8_t *)buf, res) < 0) { DEBUG("error parsing packet\n"); continue; } if ((res = coap_handle_req(&pkt, buf, bufsize)) > 0) { res = sock_udp_send(&sock, buf, res, &remote); } else { DEBUG("error handling request %d\n", (int)res); } } } return 0; }
int main(void){ //READ IN HOW MANY TAP DEVICE TO CREATE (MAX 9999) //File locker struct flock fl; pid_t tid = syscall(SYS_gettid); fl.l_type = F_RDLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ fl.l_start = 0; /* Offset from l_whence */ fl.l_len = 0; /* length, 0 = to EOF */ fl.l_pid = tid; /* our PID */ //READ THE SIZE OF TAP_CONTROL_SIZE FILE char ffile_size[2]; int file_size,tap_num; int fp = open("./coap/tap_control_size.txt", O_RDONLY); fcntl(fp, F_SETLKW, &fl); //Locks the file for reading if(0 > fp) { printf("\n tap_control_size:open() Error!!!\n"); return 1; } read(fp,ffile_size,2); //CLOSE FILE if(0 > close(fp)) { printf("\n tap_control_size:close() Error!!!\n"); return 1; } fl.l_type = F_UNLCK; /* tell it to unlock the region */ fcntl(fp, F_SETLK, &fl); /* set the region to unlocked */ file_size = (int)(ffile_size[0] - '0'); //OPEN FILE TO DETERMINE WHICH CLIENT IS THIS ONE char file_num[file_size]; fl.l_type = F_RDLCK; fp = open("./coap/tap_control.txt", O_RDONLY); fcntl(fp, F_SETLKW, &fl); //Locks the file for reading if(0 > fp) { printf("\n tap_control:open() Error!!!\n"); return 1; } read(fp,file_num,file_size); //CLOSE FILE if(0 > close(fp)) { printf("\n tap_control:close() Error!!!\n"); return 1; } fl.l_type = F_UNLCK; /* tell it to unlock the region */ fcntl(fp, F_SETLK, &fl); /* set the region to unlocked */ //CONVERT IT TO INT tap_num=0; if(file_size == 4){ tap_num += (int)(file_num[0] - '0')*1000; tap_num += (int)(file_num[1] - '0')*100; tap_num += (int)(file_num[2] - '0')*10; tap_num += (int)(file_num[3] - '0'); } else if(file_size == 3){ tap_num += (int)(file_num[0] - '0')*100; tap_num += (int)(file_num[1] - '0')*10; tap_num += (int)(file_num[2] - '0'); } else if(file_size == 2){ tap_num += (int)(file_num[0] - '0')*10; tap_num += (int)(file_num[1] - '0'); } else tap_num += (int)(file_num[0] - '0'); //CREATE TAP DEVICE puts("Starting the RIOT\n"); int fd; char name[3+file_size]; strcpy(name,"tap"); int i; for(i=0;i<file_size;i++) name[3+i]=file_num[i]; name[3+file_size]=0; printf("TAP DEIVCE: %s\n",name); struct sockaddr_in6 servaddr; // struct ifreq ifr;// struct sockaddr_in6 cliaddr; uint8_t buf[4096]; uint8_t scratch_raw[4096]; coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)}; fd = socket(AF_INET6,SOCK_DGRAM,0);//Socket file descriptor init bzero(&servaddr,sizeof(servaddr)); servaddr.sin6_family = AF_INET6;//inet family servaddr.sin6_flowinfo = 0;//?? int ip8_1=0,ip8_2=0; servaddr.sin6_addr.s6_addr[0] = (uint8_t)0x30;//IPv6 Address 1 servaddr.sin6_addr.s6_addr[1] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[2] = (uint8_t)0x00;//IPv6 Address 2 servaddr.sin6_addr.s6_addr[3] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[4] = (uint8_t)0x00;//IPv6 Address 3 servaddr.sin6_addr.s6_addr[5] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[6] = (uint8_t)0x00;//IPv6 Address 4 servaddr.sin6_addr.s6_addr[7] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[8] = (uint8_t)0x11;//IPv6 Address 5 servaddr.sin6_addr.s6_addr[9] = (uint8_t)0x11; servaddr.sin6_addr.s6_addr[10] = (uint8_t)0x22;//IPv6 Address 6 servaddr.sin6_addr.s6_addr[11] = (uint8_t)0x22; servaddr.sin6_addr.s6_addr[12] = (uint8_t)0x33;//IPv6 Address 7 servaddr.sin6_addr.s6_addr[13] = (uint8_t)0x33; if(file_size == 4){ ip8_1 += (int)(file_num[0] - '0')*16; ip8_1 += (int)(file_num[1] - '0'); ip8_2 += (int)(file_num[2] - '0')*16; ip8_2 += (int)(file_num[3] - '0'); } else if(file_size == 3){ ip8_1 += (int)(file_num[0] - '0'); ip8_2 += (int)(file_num[1] - '0')*16; ip8_2 += (int)(file_num[2] - '0'); } else if(file_size == 2){ ip8_2 += (int)(file_num[0] - '0')*16; ip8_2 += (int)(file_num[1] - '0'); } else ip8_2 += (int)(file_num[0] - '0'); servaddr.sin6_addr.s6_addr[14] = (uint8_t)ip8_1;//IPv6 Address 8 //TODO servaddr.sin6_addr.s6_addr[15] = (uint8_t)ip8_2; servaddr.sin6_port = htons(PORT); //PORT (5683) bind(fd,(struct sockaddr *)&servaddr, sizeof(servaddr)); endpoint_setup(); while(1) { int n, rc; socklen_t len = sizeof(cliaddr); coap_packet_t pkt; n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len); //#ifdef DEBUG printf("Received: "); coap_dump(buf, n, true); printf("\n"); //#endif if (0 != (rc = coap_parse(&pkt, buf, n))) printf("Bad packet rc=%d\n", rc); else { size_t rsplen = sizeof(buf); coap_packet_t rsppkt; #ifdef DEBUG coap_dumpPacket(&pkt); #endif coap_handle_req(&scratch_buf, &pkt, &rsppkt); if (0 != (rc = coap_build(buf, &rsplen, &rsppkt))) printf("coap_build failed rc=%d\n", rc); else { #ifdef DEBUG printf("Sending: "); coap_dump(buf, rsplen, true); printf("\n"); #endif #ifdef DEBUG coap_dumpPacket(&rsppkt); #endif sendto(fd, buf, rsplen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); } } } }
int main(void) { int fd; #ifdef IPV6 struct sockaddr_in6 servaddr, cliaddr; #else /* IPV6 */ struct sockaddr_in servaddr, cliaddr; #endif /* IPV6 */ uint8_t buf[1024]; #ifdef IPV6 fd = socket(AF_INET6,SOCK_DGRAM,0); #else /* IPV6 */ fd = socket(AF_INET,SOCK_DGRAM,0); #endif /* IPV6 */ bzero(&servaddr,sizeof(servaddr)); #ifdef IPV6 servaddr.sin6_family = AF_INET6; servaddr.sin6_addr = in6addr_any; servaddr.sin6_port = htons(COAP_DEFAULT_PORT); #else /* IPV6 */ servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(COAP_DEFAULT_PORT); #endif /* IPV6 */ bind(fd,(struct sockaddr *)&servaddr, sizeof(servaddr)); resource_setup(resources); while(1) { int n, rc; socklen_t len = sizeof(cliaddr); coap_packet_t pkt; n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len); #ifdef YACOAP_DEBUG printf("Received: "); coap_dump(buf, n, true); printf("\n"); #endif if ((rc = coap_parse(buf, n, &pkt)) > COAP_ERR) printf("Bad packet rc=%d\n", rc); else { size_t buflen = sizeof(buf); coap_packet_t rsppkt; #ifdef YACOAP_DEBUG coap_dump_packet(&pkt); #endif coap_handle_request(resources, &pkt, &rsppkt); if ((rc = coap_build(&rsppkt, buf, &buflen)) > COAP_ERR) printf("coap_build failed rc=%d\n", rc); else { #ifdef YACOAP_DEBUG printf("Sending: "); coap_dump(buf, buflen, true); printf("\n"); #endif #ifdef YACOAP_DEBUG coap_dump_packet(&rsppkt); #endif sendto(fd, buf, buflen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); } } } }
static void *coap_server_thread(void *args) { struct sockaddr_in6 server_addr; uint16_t port; coap_packet_t inpkt; coap_packet_t outpkt; int bad_packet; size_t rsplen; msg_init_queue(server_msg_queue, SERVER_MSG_QUEUE_SIZE); server_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); /* parse port */ port = (uint16_t)atoi((char *)args); if (port == 0) { puts("ERROR: invalid port specified"); return NULL; } server_addr.sin6_family = AF_INET6; memset(&server_addr.sin6_addr, 0, sizeof(server_addr.sin6_addr)); server_addr.sin6_port = htons(port); if (server_socket < 0) { puts("ERROR initializing socket"); server_socket = 0; return NULL; } if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { server_socket = -1; puts("ERROR binding socket"); return NULL; } printf("Success: started UDP server on port %" PRIu16 "\n", port); while (1) { int res; struct sockaddr_in6 src; socklen_t src_len = sizeof(struct sockaddr_in6); res = recvfrom(server_socket, server_buffer, sizeof(server_buffer), 0, (struct sockaddr *)&src, &src_len); if (res < 0) { puts("ERROR on receive"); continue; } if (res == 0) { puts("Peer shut down"); continue; } printf("Received data: "); puts(server_buffer); bad_packet = coap_parse(&inpkt, (uint8_t *)server_buffer, res); if (bad_packet) { puts("ERROR: malformed CoAP packet"); continue; } coap_dump_packet(&inpkt); bad_packet = coap_handle_req(&scratch, &inpkt, &outpkt, true, false); if (bad_packet) { puts("ERROR: coap_handle_req failed"); } bad_packet = coap_build(pkt_buf, &rsplen, &outpkt); if (bad_packet) { printf("ERROR: could not build CoAP packet: %d\n", bad_packet); continue; } res = sendto(server_socket, (void *)&pkt_buf, rsplen, 0, (struct sockaddr *)&src, src_len); if (res == -1) { puts("ERROR: could not send reply"); } } return NULL; }
void ICACHE_FLASH_ATTR coap_server(void *pvParameters) { int fd; struct sockaddr_in servaddr, cliaddr; coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)}; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { // shell_printf("\nSocket Error\r\n"); return; } servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); memset(&(servaddr.sin_zero), 0, sizeof(servaddr.sin_zero)); if ((bind(fd, (struct sockaddr *)&servaddr, sizeof(servaddr))) == -1) { // shell_printf("Bind error\r\n"); return; } endpoint_setup(); // shell_printf("Coap Server Start!\r\n"); while (1) { int n, rc; socklen_t len = sizeof(cliaddr); coap_packet_t pkt; n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len); #ifdef MICROCOAP_DEBUG // shell_printf("\r\n--------------------\r\n"); // shell_printf("Received Buffer: \r\n"); // coap_dump(buf, n, true); // shell_printf("\r\n"); #endif if (0 != (rc = coap_parse(&pkt, buf, n))) { // shell_printf("Bad packet rc\r\n"); // shell_printf("Bad packet rc=%d\r\n", rc); } else { size_t rsplen = sizeof(buf); coap_packet_t rsppkt; // printf("Dump Packet: \r\n"); // coap_dumpPacket(&pkt); coap_handle_req(&scratch_buf, &pkt, &rsppkt); if (0 != (rc = coap_build(buf, &rsplen, &rsppkt))) { // printf("coap_build failed rc=%d\n", rc); } else { // shell_printf("--------------------\r\n"); // shell_printf("Sending Buffer: \r\n"); // coap_dump(buf, rsplen, true); // printf("\r\n"); // coap_dumpPacket(&rsppkt); sendto(fd, buf, rsplen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); } } } }
int main(int argc, char **argv) { (void)argc; (void)argv; puts("Starting the RIOT\n"); int fd,tap_fd; const char *clonedev = "/dev/net/tun"; char *name = "tap0"; struct sockaddr_in6 servaddr, cliaddr; struct ifreq ifr; uint8_t buf[4096]; uint8_t scratch_raw[4096]; coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)}; fd = socket(AF_INET6,SOCK_DGRAM,0);//Socket file descriptor init bzero(&servaddr,sizeof(servaddr)); servaddr.sin6_family = AF_INET6;//inet family servaddr.sin6_flowinfo = 0;//?? servaddr.sin6_addr.s6_addr[0] = (uint8_t)0x30;//IPv6 Address 1 servaddr.sin6_addr.s6_addr[1] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[2] = (uint8_t)0x00;//IPv6 Address 2 servaddr.sin6_addr.s6_addr[3] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[4] = (uint8_t)0x00;//IPv6 Address 3 servaddr.sin6_addr.s6_addr[5] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[6] = (uint8_t)0x00;//IPv6 Address 4 servaddr.sin6_addr.s6_addr[7] = (uint8_t)0x00; servaddr.sin6_addr.s6_addr[8] = (uint8_t)0x11;//IPv6 Address 5 servaddr.sin6_addr.s6_addr[9] = (uint8_t)0x11; servaddr.sin6_addr.s6_addr[10] = (uint8_t)0x22;//IPv6 Address 6 servaddr.sin6_addr.s6_addr[11] = (uint8_t)0x22; servaddr.sin6_addr.s6_addr[12] = (uint8_t)0x33;//IPv6 Address 7 servaddr.sin6_addr.s6_addr[13] = (uint8_t)0x33; servaddr.sin6_addr.s6_addr[14] = (uint8_t)0x00;//IPv6 Address 8 servaddr.sin6_addr.s6_addr[15] = (uint8_t)0x01; servaddr.sin6_port = htons(PORT); //PORT (5683) bind(fd,(struct sockaddr *)&servaddr, sizeof(servaddr)); //Set TAP device up, give it local ipv6 address /* implicitly create the tap interface */ if ((tap_fd = real_open(clonedev , O_RDWR)) == -1) { err(EXIT_FAILURE, "open(%s)", clonedev); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, name, IFNAMSIZ); if (real_ioctl(tap_fd, TUNSETIFF, (void *)&ifr) == -1) { _native_in_syscall++; warn("ioctl TUNSETIFF"); warnx("probably the tap interface (%s) does not exist or is already in use", name); real_exit(EXIT_FAILURE); } //TODO Add Global IP endpoint_setup(); while(1) { int n, rc; socklen_t len = sizeof(cliaddr); coap_packet_t pkt; n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len); //#ifdef DEBUG printf("Received: "); coap_dump(buf, n, true); printf("\n"); //#endif if (0 != (rc = coap_parse(&pkt, buf, n))) printf("Bad packet rc=%d\n", rc); else { size_t rsplen = sizeof(buf); coap_packet_t rsppkt; #ifdef DEBUG coap_dumpPacket(&pkt); #endif coap_handle_req(&scratch_buf, &pkt, &rsppkt); if (0 != (rc = coap_build(buf, &rsplen, &rsppkt))) printf("coap_build failed rc=%d\n", rc); else { #ifdef DEBUG printf("Sending: "); coap_dump(buf, rsplen, true); printf("\n"); #endif #ifdef DEBUG coap_dumpPacket(&rsppkt); #endif sendto(fd, buf, rsplen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); } } } }
void CoapServ(void* parg) { int fd; struct sockaddr_in servaddr, cliaddr; coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)}; (void)parg; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { printf("Socket Error\r\n"); exit(0); } servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(COAPSERV_PORT); memset(&(servaddr.sin_zero), 0, sizeof(servaddr.sin_zero)); if ((bind(fd, (struct sockaddr *)&servaddr, sizeof(servaddr))) == -1) { printf("Bind error\r\n"); exit(0); } endpoint_setup(); printf("Coap Server Start!\r\n"); while(1) { int n, rc; socklen_t len = sizeof(cliaddr); coap_packet_t pkt; n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len); if (0 != (rc = coap_parse(&pkt, buf, n))) { printf("Bad packet rc=%d\r\n", rc); } else { printf("payload : %s \r\n", pkt.payload.p); //coapServ reply client { size_t rsplen = sizeof(buf); coap_packet_t rsppkt; coap_handle_req(&scratch_buf, &pkt, &rsppkt); if (0 != (rc = coap_build(buf, &rsplen, &rsppkt))) { printf("coap_build failed rc=%d\n", rc); } else { sendto(fd, buf, rsplen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); } } } }/*while(1)--END*/ }
/* Listen for an incoming CoAP message. */ static void _listen(sock_udp_t *sock) { coap_pkt_t pdu; uint8_t buf[GCOAP_PDU_BUF_SIZE]; sock_udp_ep_t remote; gcoap_request_memo_t *memo = NULL; uint8_t open_reqs = gcoap_op_state(); /* We expect a -EINTR response here when unlimited waiting (SOCK_NO_TIMEOUT) * is interrupted when sending a message in gcoap_req_send2(). While a * request is outstanding, sock_udp_recv() is called here with limited * waiting so the request's timeout can be handled in a timely manner in * _event_loop(). */ ssize_t res = sock_udp_recv(sock, buf, sizeof(buf), open_reqs > 0 ? GCOAP_RECV_TIMEOUT : SOCK_NO_TIMEOUT, &remote); if (res <= 0) { #if ENABLE_DEBUG if (res < 0 && res != -ETIMEDOUT) { DEBUG("gcoap: udp recv failure: %d\n", res); } #endif return; } res = coap_parse(&pdu, buf, res); if (res < 0) { DEBUG("gcoap: parse failure: %d\n", (int)res); /* If a response, can't clear memo, but it will timeout later. */ return; } if (pdu.hdr->code == COAP_CODE_EMPTY) { DEBUG("gcoap: empty messages not handled yet\n"); return; } /* validate class and type for incoming */ switch (coap_get_code_class(&pdu)) { /* incoming request */ case COAP_CLASS_REQ: if (coap_get_type(&pdu) == COAP_TYPE_NON || coap_get_type(&pdu) == COAP_TYPE_CON) { size_t pdu_len = _handle_req(&pdu, buf, sizeof(buf), &remote); if (pdu_len > 0) { ssize_t bytes = sock_udp_send(sock, buf, pdu_len, &remote); if (bytes <= 0) { DEBUG("gcoap: send response failed: %d\n", (int)bytes); } } } else { DEBUG("gcoap: illegal request type: %u\n", coap_get_type(&pdu)); } break; /* incoming response */ case COAP_CLASS_SUCCESS: case COAP_CLASS_CLIENT_FAILURE: case COAP_CLASS_SERVER_FAILURE: _find_req_memo(&memo, &pdu, &remote); if (memo) { switch (coap_get_type(&pdu)) { case COAP_TYPE_NON: case COAP_TYPE_ACK: xtimer_remove(&memo->response_timer); memo->state = GCOAP_MEMO_RESP; if (memo->resp_handler) { memo->resp_handler(memo->state, &pdu, &remote); } if (memo->send_limit >= 0) { /* if confirmable */ *memo->msg.data.pdu_buf = 0; /* clear resend PDU buffer */ } memo->state = GCOAP_MEMO_UNUSED; break; case COAP_TYPE_CON: DEBUG("gcoap: separate CON response not handled yet\n"); break; default: DEBUG("gcoap: illegal response type: %u\n", coap_get_type(&pdu)); break; } } else { DEBUG("gcoap: msg not found for ID: %u\n", coap_get_id(&pdu)); } break; default: DEBUG("gcoap: illegal code class: %u\n", coap_get_code_class(&pdu)); } }