void http_get_task(void *pvParameters) { coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ int failures = 0; // create network socket struct addrinfo hints; struct addrinfo *res; // Use an UDP socket hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; // Get host/port from request URL // should call free(uri) somewhere coap_uri_t *uri = coap_new_uri((unsigned char*)URI, strlen(URI)); if (uri == NULL) { COAP_PRINTF("coap_new_uri(): URI failed\n"); vTaskDelete(NULL); } // DNS lookup int err; char port[6]; char host[32]; char path[64]; sprintf(port, "%d", uri->port); sprintf(path, "%s", uri->path.s); memcpy(host, uri->host.s, uri->host.length); host[uri->host.length] = '\0'; COAP_PRINTF("URI Path: %s\n", path); COAP_PRINTF("URI Host: %s\n", host); COAP_PRINTF("URI Port: %s\n", port); printf("Running DNS lookup for %s...\r\n", host); while (1) { err = getaddrinfo(host, port, &hints, &res); if (err == 0) break; freeaddrinfo(res); printf("DNS lookup failed err=%d res=%p\r\n", err, res); vTaskDelay(3000 / portTICK_RATE_MS); } /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; char *ip = inet_ntoa(*addr); printf("DNS lookup succeeded. HOST=%s, IP=%s\r\n", host, ip); // init a HTTP POST message and set message header coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, path); coap_set_header_uri_host(request, host); // Create a local socket int s = socket(res->ai_family, res->ai_socktype, 0); if(s < 0) { printf("... Failed to allocate socket.\r\n"); freeaddrinfo(res); vTaskDelete(NULL); } printf("... allocated socket\r\n"); int a; int ret; char payload[128]; struct request_state_t state[1]; ip_addr_t ipaddr; ipaddr.addr = ipaddr_addr(ip); while(1) { if(connect(s, res->ai_addr, res->ai_addrlen) != 0) { close(s); freeaddrinfo(res); printf("... socket connect failed.\r\n"); vTaskDelay(3000 / portTICK_RATE_MS); failures++; continue; } printf("... connected\r\n"); freeaddrinfo(res); repeat: vTaskDelay(5000 / portTICK_RATE_MS); // read sensor data from ESP8266 A0 a = sdk_system_adc_read(); sprintf(payload, "{ \"quality\": %d }\n", a); COAP_PRINTF("Payload: %s\n", payload); // CoAP payload coap_set_payload(request, payload, strlen(payload)); // Make CoAP transaction request->mid = coap_get_mid(); if ((state->transaction = coap_new_transaction(request->mid, &ipaddr, uri->port))) { state->transaction->callback = coap_blocking_request_callback; state->transaction->callback_data = state; if (state->block_num > 0) { coap_set_header_block2(request, state->block_num, 0, REST_MAX_CHUNK_SIZE); } // Build CoAP header and Options state->transaction->packet_len = coap_serialize_message(request, state->transaction->packet); COAP_PRINTF("Header dump: [0x%02X %02X %02X %02X]. Size: %d\n", request->buffer[0], request->buffer[1], request->buffer[2], request->buffer[3], state->transaction->packet_len ); COAP_PRINTF("Requested #%u (MID %u)\n", state->block_num, request->mid); // Transmit ret = write(s, state->transaction->packet, state->transaction->packet_len); //ret = sendto(s, state->transaction->packet, state->transaction->packet_len); if (ret < 0) { printf("[RET: %d] CoAP packet send failed.\n", ret); continue; } } else { COAP_PRINTF("Could not allocate transaction buffer"); } goto repeat; } }
void transmitTask(void *pvParameters) { struct userdata *user = (struct userdata *)pvParameters; coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ int a; char payload[128]; int failures = 0; // Get host/port from request URL // should call free(uri) somewhere coap_uri_t *uri = coap_new_uri(SERVER_URI, strlen(SERVER_URI)); if (uri == NULL) { COAP_PRINTF("coap_new_uri(): URI failed\n"); vTaskDelete(NULL); } COAP_PRINTF("URI Path: %s\n", uri->path.s); COAP_PRINTF("URI Host: %s\n", uri->host.s); // init a HTTP POST message and set message header coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, (char *)uri->path.s); coap_set_header_uri_host(request, (char *)uri->host.s); // create network socket struct addrinfo hints; struct addrinfo *res; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; // 2. DNS lookup int err; char port[6]; sprintf(port, "%d", uri->port); printf("Running DNS lookup for %s...\r\n", uri->host.s); while (1) { err = getaddrinfo((char*)uri->host.s, (char*)port, &hints, &res); if (err == 0) break; freeaddrinfo(res); printf("DNS lookup failed err=%d res=%p\r\n", err, res); vTaskDelay(3000 / portTICK_RATE_MS); } /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(*addr)); // 3. Create a local socket int s = socket(res->ai_family, res->ai_socktype, 0); if(s < 0) { printf("... Failed to allocate socket.\r\n"); freeaddrinfo(res); vTaskDelete(NULL); } printf("... allocated socket\r\n"); int ret; while(1) { // connect to server if (connect(s, res->ai_addr, res->ai_addrlen) != 0) { close(s); freeaddrinfo(res); failures++; printf("... socket connect failed. tries = %d.\r\n", failures); vTaskDelay(4000 / portTICK_RATE_MS); continue; } printf("... connected\r\n"); freeaddrinfo(res); repeat: xQueueReceive(user->xQueue, &a, portMAX_DELAY); sprintf(payload, "{ \"quality\": %d }\n", a); COAP_PRINTF("Payload: %s\n", payload); // CoAP payload coap_set_payload(request, payload, strlen(payload)); ret = write(s, payload, strlen(payload)); if (ret >= 0) goto repeat; } }