rpmsg_ns.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-02-25 GuEe-GUI the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #define DBG_TAG "rpmsg.ns"
  13. #define DBG_LVL DBG_INFO
  14. #include <rtdbg.h>
  15. /*
  16. * Used when rt_rpmsg_create_endpoint(..., RT_NULL) (e.g. remote NS announce);
  17. * application traffic should be bound via a higher layer later.
  18. */
  19. static rt_err_t rpmsg_ns_remote_default_rx(struct rt_rpmsg_device *rdev,
  20. rt_uint32_t src, void *data, rt_size_t len)
  21. {
  22. LOG_D("%s: remote endpoint rx (no user cb), src=%u len=%u", rt_dm_dev_get_name(&rdev->parent), src, len);
  23. return RT_EOK;
  24. }
  25. static rt_err_t rpmsg_ns_rx_callback(struct rt_rpmsg_device *rdev,
  26. rt_uint32_t src, void *data, rt_size_t len)
  27. {
  28. rt_err_t err = RT_EOK;
  29. struct rt_rpmsg_ns_msg *msg = data;
  30. struct rt_rpmsg_endpoint *ept;
  31. struct rt_rpmsg_endpoint_info info;
  32. if (len != sizeof(*msg))
  33. {
  34. LOG_E("Invalid MSG size = %d", len);
  35. return -RT_EINVAL;
  36. }
  37. /* Fixup the name */
  38. msg->name[RT_RPMSG_NAME_SIZE - 1] = '\0';
  39. rt_strncpy(info.name, msg->name, RT_RPMSG_NAME_SIZE);
  40. info.src = RT_RPMSG_ADDR_ANY;
  41. info.dst = rt_le32_to_cpu(msg->addr);
  42. LOG_D("%s: name: %s, src: %u, dst: %u", rt_dm_dev_get_name(&rdev->parent),
  43. info.name, info.src, info.dst);
  44. if (rt_le32_to_cpu(msg->flags) & RT_RPMSG_NS_DESTROY)
  45. {
  46. ept = rt_rpmsg_find_endpoint(rdev, &info);
  47. if (ept)
  48. {
  49. err = rt_rpmsg_destroy_endpoint(rdev, ept);
  50. }
  51. else
  52. {
  53. err = -RT_EEMPTY;
  54. }
  55. }
  56. else if (rt_le32_to_cpu(msg->flags) == RT_RPMSG_NS_CREATE)
  57. {
  58. ept = rt_rpmsg_create_endpoint(rdev, &info, RT_NULL);
  59. if (rt_is_err(ept))
  60. {
  61. err = rt_ptr_err(ept);
  62. }
  63. }
  64. else
  65. {
  66. LOG_E("Unsupported flags = %x", rt_le32_to_cpu(msg->flags));
  67. }
  68. if (err)
  69. {
  70. LOG_E("%s: name = %s, addr = %x flags = %d error = %s",
  71. rt_dm_dev_get_name(&rdev->parent),
  72. msg->name, msg->addr, msg->flags, rt_strerror(err));
  73. }
  74. return err;
  75. }
  76. static rt_err_t rpmsg_ns_probe(struct rt_rpmsg_device *rdev)
  77. {
  78. struct rt_rpmsg_endpoint *ep;
  79. struct rt_rpmsg_endpoint_info info;
  80. rt_strncpy(info.name, "name-service", RT_RPMSG_NAME_SIZE);
  81. info.src = RT_RPMSG_NS_ADDR;
  82. info.dst = RT_RPMSG_NS_ADDR;
  83. ep = rt_rpmsg_create_endpoint(rdev, &info, &rpmsg_ns_rx_callback);
  84. return rt_is_err(ep) ? rt_ptr_err(ep) : RT_EOK;
  85. }
  86. static struct rt_rpmsg_device_id rpmsg_ns_ids[] =
  87. {
  88. { .name = "rpmsg-name-service" },
  89. { /* sentinel */ }
  90. };
  91. static struct rt_rpmsg_driver rpmsg_ns_driver =
  92. {
  93. .parent.parent =
  94. {
  95. .name = "rpmsg-ns",
  96. },
  97. .ids = rpmsg_ns_ids,
  98. .probe = rpmsg_ns_probe,
  99. .rx_callback = rpmsg_ns_remote_default_rx,
  100. };
  101. RT_RPMSG_DRIVER_EXPORT(rpmsg_ns_driver);