int rest_get_query_variable(REQUEST* request, const char *name, char* output, uint16_t output_size) { #ifdef WITH_COAP return coap_get_query_variable(request, name, output, output_size); #else return http_get_query_variable(request, name, output, output_size); #endif /*WITH_COAP*/ }
void well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { size_t strpos = 0; /* position in overall string (which is larger than the buffer) */ size_t bufpos = 0; /* position within buffer (bytes written) */ size_t tmplen = 0; resource_t* resource = NULL; /* For filtering. */ const char *filter = NULL; int len = coap_get_query_variable(request, "rt", &filter); char *rt = NULL; for (resource = (resource_t*)list_head(rest_get_resources()); resource; resource = resource->next) { /* Filtering */ if (len && ((rt=strstr(resource->attributes, "rt=\""))==NULL || memcmp(rt+4, filter, len-1)!=0 || (filter[len-1]!='*' && (filter[len-1]!=rt[3+len] || rt[4+len]!='"')))) { continue; } PRINTF("res: /%s (%p)\npos: s%d, o%d, b%d\n", resource->url, resource, strpos, *offset, bufpos); if (strpos >= *offset && bufpos < preferred_size) { buffer[bufpos++] = '<'; } ++strpos; if (strpos >= *offset && bufpos < preferred_size) { buffer[bufpos++] = '/'; } ++strpos; tmplen = strlen(resource->url); if (strpos+tmplen > *offset) { bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, "%s", resource->url + ((*offset-(int32_t)strpos > 0) ? (*offset-(int32_t)strpos) : 0)); /* minimal-net requires these casts */ if (bufpos >= preferred_size) { break; } } strpos += tmplen; if (strpos >= *offset && bufpos < preferred_size) { buffer[bufpos++] = '>'; } ++strpos; if (resource->attributes[0]) { if (strpos >= *offset && bufpos < preferred_size) { buffer[bufpos++] = ';'; } ++strpos; tmplen = strlen(resource->attributes); if (strpos+tmplen > *offset) { bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, "%s", resource->attributes + (*offset-(int32_t)strpos > 0 ? *offset-(int32_t)strpos : 0)); if (bufpos >= preferred_size) { break; } } strpos += tmplen; } if (resource->next) { if (strpos >= *offset && bufpos < preferred_size) { buffer[bufpos++] = ','; } ++strpos; } /* buffer full, but resource not completed yet; or: do not break if resource exactly fills buffer. */ if (bufpos >= preferred_size && strpos-bufpos > *offset) { PRINTF("res: BREAK at %s (%p)\n", resource->url, resource); break; } } if (bufpos>0) { PRINTF("BUF %d: %.*s\n", bufpos, bufpos, (char *) buffer); coap_set_payload(response, buffer, bufpos ); coap_set_header_content_type(response, APPLICATION_LINK_FORMAT); } else if (strpos>0) { PRINTF("well_known_core_handler(): bufpos<=0\n"); coap_set_status_code(response, BAD_OPTION_4_02); coap_set_payload(response, "BlockOutOfScope", 15); } if (resource==NULL) { PRINTF("res: DONE\n"); *offset = -1; } else { PRINTF("res: MORE at %s (%p)\n", resource->url, resource); *offset += preferred_size; } }