/**
* @brief Sets the topic. Only for Publish-Subscribe type.
- * @remarks The length of @a topic should be less than 63 characters.
+ * @remarks The length of @a topic should be less than 1023 characters.
* @since_tizen 6.5
* @param[in] dp The data path handle
* @param[in] topic The topic
#define VINE_MAX_HOST_NAME_LEN 255
#define VINE_MAX_IP_LEN 39 // for IPv6
#define VINE_MAX_KEY_LEN 9
+#define VINE_MAX_ATTRIBUTE_LEN 252
-#define VINE_MAX_TOPIC_LEN 63
+#define VINE_MAX_TOPIC_LEN 1023
// Actually, max length of service_type and service_name for ble cannot be restricted strictly.
// Even though the constraits is met, the operation can be failed.
void *mTerminatedCbData;
};
-class DPServer : DataPath
+class DPServer : public DataPath
{
public:
DPServer(void *event_queue);
void *mAcceptedCbData;
};
-class DPClient : DataPath
+class DPClient : public DataPath
{
public:
DPClient(void *event_queue);
#define VINE_DP_PUBSUB_RANK_LEN 6
#define VINE_DP_PUBSUB_OPEN_TIMEOUT_MS 2000
-class DPPubSub : DataPath
+class DPPubSub : public DataPath
{
public:
DPPubSub(void *event_queue);
virtual int get_remote_port();
virtual int get_ip(vine_address_family_e *addr_family, char **ip);
virtual int set_port(int port);
- virtual int get_port(){ return mListenPort; };
+ virtual int get_port() { return mListenPort; }
virtual int update_local_address_info();
virtual int set_topic(std::string topic);
+ virtual std::string get_topic() { return mTopic; }
virtual int set_max_connections(int max_conn);
virtual int set_accepted_cb(vine_dp_accepted_cb callback, void *user_data);
virtual int unset_accepted_cb();
int create_rank();
int compare_ip_priority(const char *peer_ip);
void create_id(char id[]);
+ std::string get_service_type(const std::string &topic);
};
}
}
+static std::string __get_full_topic(const map<string, string> &attr)
+{
+ std::string topic;
+
+ for (int i = 0; i < 5; ++i) {
+ char key[3];
+ key[0] = 'T';
+ key[1] = '0' + i;
+ key[2] = 0;
+
+ auto val = attr.find(key);
+ if (val == attr.end())
+ break;
+ topic += val->second;
+ }
+ return topic;
+}
+
static void _service_discovered_cb(vine_disc_h disc, bool available,
const char *service_type, const char *service_name,
const char *host_name, int port, const map<string, string> &attr,
if (!user_data || !available)
return;
+ DPPubSub *dp = static_cast<DPPubSub *>(user_data);
+
+ std::string discovered_topic = __get_full_topic(attr);
+ VINE_LOGD("Topic[%s] from attributes", discovered_topic.c_str());
+ std::string topic = dp->get_topic();
+ if (discovered_topic != topic) {
+ VINE_LOGD("Topic is not matched [%s] -- [%s]", discovered_topic.c_str(), topic.c_str());
+ return;
+ }
+
vine_disc_h disc_handle;
int ret = vine_disc_create(VINE_DISCOVERY_METHOD_DNS_SD, &disc_handle);
RET_IF(ret != VINE_ERROR_NONE, "Fail to create a disc");
ret = vine_disc_resolve_ip(disc_handle, service,
_ip_resolved_cb, user_data,
- (vine_event_queue_h)static_cast<DataPath *>(user_data)->get_eventfd());
+ (vine_event_queue_h)static_cast<DataPath *>(dp)->get_eventfd());
if (ret != VINE_ERROR_NONE) {
VINE_LOGE("Fail to resolve IP. error(%d)", ret);
_vine_service_destroy(service);
VINE_DP_PUBSUB_SERVICE_NAME_PREFIX, rand_str.c_str());
}
+std::string DPPubSub::get_service_type(const std::string &topic)
+{
+ return topic.substr(0, VINE_MAX_SERVICE_TYPE_LEN);
+}
+
int DPPubSub::publish_service()
{
vine_service_h service;
if (ret != VINE_ERROR_NONE)
return ret;
- vine_service_set_type(service, mTopic.c_str());
+ std::string type = get_service_type(mTopic);
+ vine_service_set_type(service, type.c_str());
+
+ int attr_num = 0;
+ int pos = 0;
+
+ // The maximum length of topic is 1024.
+ // The length of value is at most (VINE_MAX_ATTRIBUTE_LEN(252) - key length(2) - 1 = 249)
+ // Therefore, at most five attributes can be added for a topic.
+ VINE_LOGD("Topic[%s] is added as attributes", mTopic);
+ while (pos < mTopic.size()) {
+ std::string val = mTopic.substr(pos, VINE_MAX_ATTRIBUTE_LEN - 1 - 2);
+ char key[3];
+ key[0] = 'T';
+ key[1] = '0' + attr_num++;
+ key[2] = 0;
+
+ vine_service_add_attribute(service, key, val.c_str());
+ pos += val.size();
+ }
+
vine_service_set_port(service, mListenPort);
mRank = create_rank();
RET_VAL_IF(ret != VINE_ERROR_NONE, ret, "Fail to vine_disc_create");
}
+ std::string type = get_service_type(mTopic);
ret = vine_disc_subscribe(mSdSub,
- mTopic.c_str(), NULL,
+ type.c_str(), NULL,
_service_discovered_cb, static_cast<void *>(this),
mEventQueue);
if (ret != VINE_ERROR_NONE) {
return s->family;
}
-static bool __check_len_key(const char *key)
+static bool __check_len_key_val(const char *key, const char *value)
{
RET_VAL_IF(key == NULL, false, "key is NULL");
- int len = strlen(key);
- return len > 0 && len <= VINE_MAX_KEY_LEN;
+ int key_len = strlen(key);
+ int val_len = strlen(value);
+ return key_len > 0 && key_len <= VINE_MAX_KEY_LEN && key_len + val_len + 1 <= VINE_MAX_ATTRIBUTE_LEN;
}
int _vine_service_add_attribute(vine_service_h service,
const char *key, const char *value)
{
RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
- RET_VAL_IF(__check_len_key(key) == false,
- VINE_ERROR_INVALID_PARAMETER, "invalid length of key");
+ RET_VAL_IF(__check_len_key_val(key, value) == false,
+ VINE_ERROR_INVALID_PARAMETER, "invalid length of key or value");
VINE_LOGD("Key[%s] value[%s]", key, value);
CHECK_SESSION;
int port = 0;
int addr_family = 0;
- char topic[64];
+ char topic[1024];
printf(" >> Address type(0-default, 1-IPv4, 2-IPv6): ");
if (scanf(" %d", &addr_family) < 1) {
}
printf(" >> Set topic: ");
- if (scanf(" %63s", topic) < 1) {
+ if (scanf(" %1023s", topic) < 1) {
_test_print_error("Scan failed");
return;
}