static bool
filter_resource(oc_resource_t *resource, const char *rt, int rt_len,
                CborEncoder *links)
{
  int i;
  bool match = true;
  if (rt_len > 0) {
    match = false;
    for (i = 0; i < oc_string_array_get_allocated_size(resource->types); i++) {
      int size = oc_string_array_get_item_size(resource->types, i);
      const char *t =
        (const char *)oc_string_array_get_item(resource->types, i);
      if (rt_len == size && strncmp(rt, t, rt_len) == 0) {
        match = true;
        break;
      }
    }
  }

  if (!match) {
    return false;
  }

  oc_rep_start_object(*links, res);

  // uri
  oc_rep_set_text_string(res, href, oc_string(resource->uri));

  // rt
  oc_rep_set_array(res, rt);
  for (i = 0; i < oc_string_array_get_allocated_size(resource->types); i++) {
    int size = oc_string_array_get_item_size(resource->types, i);
    const char *t = (const char *)oc_string_array_get_item(resource->types, i);
    if (size > 0)
      oc_rep_add_text_string(rt, t);
  }
  oc_rep_close_array(res, rt);

  // if
  oc_core_encode_interfaces_mask(oc_rep_object(res), resource->interfaces);

  // p
  oc_rep_set_object(res, p);
  oc_rep_set_uint(p, bm, resource->properties & ~OC_PERIODIC);
#ifdef OC_SECURITY
  if (resource->properties & OC_SECURE) {
    oc_rep_set_boolean(p, sec, true);
    oc_rep_set_uint(p, port, oc_connectivity_get_dtls_port());
  }
#endif /* OC_SECURITY */

  oc_rep_close_object(res, p);

  oc_rep_end_object(*links, res);
  return true;
}
Exemple #2
0
static oc_discovery_flags_t
discovery(const char *di, const char *uri, oc_string_array_t types,
          oc_interface_mask_t interfaces, oc_server_handle_t *server)
{
    int i;
    int uri_len = strlen(uri);
    uri_len = (uri_len >= MAX_URI_LENGTH) ? MAX_URI_LENGTH - 1 : uri_len;

    for (i = 0; i < oc_string_array_get_allocated_size(types); i++) {
        char *t = oc_string_array_get_item(types, i);
        if (strlen(t) == 11 && strncmp(t, "oic.r.light", 11) == 0) {
            memcpy(&light_server, server, sizeof(oc_server_handle_t));

            strncpy(light_1, uri, uri_len);
            light_1[uri_len] = '\0';

            oc_do_observe(light_1, &light_server, NULL, &observe_light,
                          LOW_QOS);
            os_callout_reset(&callout, 30 * OS_TICKS_PER_SEC);
            return OC_STOP_DISCOVERY;
        }
    }
    return OC_CONTINUE_DISCOVERY;
}
oc_discovery_flags_t
oc_ri_process_discovery_payload(struct coap_packet_rx *rsp,
                                oc_discovery_cb_t *handler,
                                oc_endpoint_t *endpoint)
{
  oc_discovery_flags_t ret = OC_CONTINUE_DISCOVERY;
  oc_string_t uri = {
      .os_sz = 0,
      .os_str = NULL
  };
  oc_string_t di = {
      .os_sz = 0,
      .os_str = NULL
  };
  bool secure = false;
  uint16_t dtls_port = 0, default_port = endpoint->oe_ip.v6.port;
  oc_string_array_t types = {};
  oc_interface_mask_t interfaces = 0;
  oc_server_handle_t handle;
  uint16_t data_off;
  struct os_mbuf *m;
  int len;

  memcpy(&handle.endpoint, endpoint, sizeof(oc_endpoint_t));

  oc_rep_t *array = 0, *rep;

  len = coap_get_payload(rsp, &m, &data_off);
  int s = oc_parse_rep(m, data_off, len, &rep);
  if (s == 0)
    array = rep;
  while (array != NULL) {
    oc_rep_t *device_map = array->value_object;
    while (device_map != NULL) {
      switch (device_map->type) {
      case STRING:
        if (oc_string_len(device_map->name) == 2 &&
            strncmp(oc_string(device_map->name), "di", 2) == 0)
          di = device_map->value_string;
        break;
      default:
        break;
      }
      device_map = device_map->next;
    }
    device_map = array->value_object;
    while (device_map != NULL) {
      switch (device_map->type) {
      case OBJECT_ARRAY: {
        oc_rep_t *links = device_map->value_object_array;
        while (links != NULL) {
          switch (links->type) {
          case OBJECT: {
            oc_rep_t *resource_info = links->value_object;
            while (resource_info != NULL) {
              switch (resource_info->type) {
              case STRING:
                uri = resource_info->value_string;
                break;
              case STRING_ARRAY:
                if (oc_string_len(resource_info->name) == 2 &&
                    strncmp(oc_string(resource_info->name), "rt", 2) == 0)
                  types = resource_info->value_array;
                else {
                  interfaces = 0;
                  int i;
                  for (i = 0; i < oc_string_array_get_allocated_size(
                                    resource_info->value_array);
                       i++) {
                    interfaces |= oc_ri_get_interface_mask(
                      oc_string_array_get_item(resource_info->value_array, i),
                      oc_string_array_get_item_size(resource_info->value_array,
                                                    i));
                  }
                }
                break;
              case OBJECT: {
                oc_rep_t *policy_info = resource_info->value_object;
                while (policy_info != NULL) {
                  if (policy_info->type == INT &&
                      oc_string_len(policy_info->name) == 4 &&
                      strncmp(oc_string(policy_info->name), "port", 4) == 0) {
                    dtls_port = policy_info->value_int;
                  }
                  if (policy_info->type == BOOL &&
                      oc_string_len(policy_info->name) == 3 &&
                      strncmp(oc_string(policy_info->name), "sec", 3) == 0 &&
                      policy_info->value_boolean == true) {
                    secure = true;
                  }
                  policy_info = policy_info->next;
                }
              } break;
              default:
                break;
              }
              resource_info = resource_info->next;
            }
            if (secure) {
              handle.endpoint.oe_ip.v6.port = dtls_port;
              handle.endpoint.oe_ip.flags |= SECURED;
            } else {
              handle.endpoint.oe_ip.v6.port = default_port;
              handle.endpoint.oe_ip.flags &= ~SECURED;
            }

            if (handler(oc_string(di), oc_string(uri), types, interfaces,
                        &handle) == OC_STOP_DISCOVERY) {
              ret = OC_STOP_DISCOVERY;
              goto done;
            }
            dtls_port = 0;
            secure = false;
          } break;
          default:
            break;
          }
          links = links->next;
        }
      } break;
      default:
        break;
      }
      device_map = device_map->next;
    }
    array = array->next;
  }
done:
  oc_free_rep(rep);
  return ret;
}
/* Parse single property */
static void
oc_parse_rep_value(CborValue *value, oc_rep_t **rep, CborError *err)
{
  size_t k, len;
  CborValue map, array;
  *rep = _alloc_rep();
  oc_rep_t *cur = *rep, **prev = 0;
  cur->next = 0;
  cur->value_object_array = 0;
  /* key */
  *err |= cbor_value_calculate_string_length(value, &len);
  len++;
  oc_alloc_string(&cur->name, len);
  *err |= cbor_value_copy_text_string(value, (char *)oc_string(cur->name), &len,
                                      NULL);
  *err |= cbor_value_advance(value);
  /* value */
  switch (value->type) {
  case CborIntegerType:
    *err |= cbor_value_get_int64(value, &cur->value_int);
    cur->type = INT;
    break;
  case CborBooleanType:
    *err |= cbor_value_get_boolean(value, &cur->value_boolean);
    cur->type = BOOL;
    break;
  case CborDoubleType:
    *err |= cbor_value_get_double(value, &cur->value_double);
    cur->type = DOUBLE;
    break;
  case CborByteStringType:
    *err |= cbor_value_calculate_string_length(value, &len);
    len++;
    oc_alloc_string(&cur->value_string, len);
    *err |= cbor_value_copy_byte_string(
      value, oc_cast(cur->value_string, uint8_t), &len, NULL);
    cur->type = BYTE_STRING;
    break;
  case CborTextStringType:
    *err |= cbor_value_calculate_string_length(value, &len);
    len++;
    oc_alloc_string(&cur->value_string, len);
    *err |= cbor_value_copy_text_string(value, oc_string(cur->value_string),
                                        &len, NULL);
    cur->type = STRING;
    break;
  case CborMapType: /* when value is a map/object */ {
    oc_rep_t **obj = &cur->value_object; // object points to list of properties
    *err |= cbor_value_enter_container(value, &map);
    while (!cbor_value_at_end(&map)) {
      oc_parse_rep_value(&map, obj, err);
      (*obj)->next = 0;
      obj = &(*obj)->next;
      *err |= cbor_value_advance(&map);
    }
    cur->type = OBJECT;
  } break;
  case CborArrayType:
    *err |= cbor_value_enter_container(value, &array);
    len = 0;
    cbor_value_get_array_length(value, &len);
    if (len == 0) {
      CborValue t = array;
      while (!cbor_value_at_end(&t)) {
        len++;
        cbor_value_advance(&t);
      }
    }
    k = 0;
    while (!cbor_value_at_end(&array)) {
      switch (array.type) {
      case CborIntegerType:
        if (k == 0) {
          oc_new_int_array(&cur->value_array, len);
          cur->type = INT | ARRAY;
        }
        *err |=
          cbor_value_get_int64(&array, oc_int_array(cur->value_array) + k);
        break;
      case CborDoubleType:
        if (k == 0) {
          oc_new_double_array(&cur->value_array, len);
          cur->type = DOUBLE | ARRAY;
        }
        *err |=
          cbor_value_get_double(&array, oc_double_array(cur->value_array) + k);
        break;
      case CborBooleanType:
        if (k == 0) {
          oc_new_bool_array(&cur->value_array, len);
          cur->type = BOOL | ARRAY;
        }
        *err |=
          cbor_value_get_boolean(&array, oc_bool_array(cur->value_array) + k);
        break;
      case CborByteStringType:
        if (k == 0) {
          oc_new_string_array(&cur->value_array, len);
          cur->type = BYTE_STRING | ARRAY;
        }
        *err |= cbor_value_calculate_string_length(&array, &len);
        len++;
        *err |= cbor_value_copy_byte_string(
          &array, (uint8_t *)oc_string_array_get_item(cur->value_array, k),
          &len, NULL);
        break;
      case CborTextStringType:
        if (k == 0) {
          oc_new_string_array(&cur->value_array, len);
          cur->type = STRING | ARRAY;
        }
        *err |= cbor_value_calculate_string_length(&array, &len);
        len++;
        *err |= cbor_value_copy_text_string(
          &array, (char *)oc_string_array_get_item(cur->value_array, k), &len,
          NULL);
        break;
      case CborMapType:
        if (k == 0) {
          cur->type = OBJECT | ARRAY;
          cur->value_object_array = _alloc_rep();
          prev = &cur->value_object_array;
        } else {
          (*prev)->next = _alloc_rep();
          prev = &(*prev)->next;
        }
        (*prev)->type = OBJECT;
        (*prev)->next = 0;
        oc_rep_t **obj = &(*prev)->value_object;
        /* Process a series of properties that make up an object of the array */
        *err |= cbor_value_enter_container(&array, &map);
        while (!cbor_value_at_end(&map)) {
          oc_parse_rep_value(&map, obj, err);
          obj = &(*obj)->next;
          *err |= cbor_value_advance(&map);
        }
        break;
      default:
        break;
      }
      k++;
      *err |= cbor_value_advance(&array);
    }
    break;
  default:
    break;
  }
}