-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deepstream 5.0 Subscription Implementation #1
base: master
Are you sure you want to change the base?
Changes from 21 commits
2e29abb
2a7a3d6
9a5bc7a
b2c6940
bf90453
67dffec
5ca5006
4821a94
adc30df
f8f0099
7aa84e7
9a8ff42
bd3310d
7e4b8d9
f2cd2b9
3707004
2fd20b1
072dfbb
93deacc
9c1449a
fa94cc3
525ee45
579d7b4
d330130
819cdc0
0bac762
ef454fb
9c61435
d9fa5a6
54fff91
c99d2de
0c7895e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -33,20 +33,26 @@ | |||||||
#include "aws_config_parser.h" | ||||||||
#include "nvds_msgapi.h" | ||||||||
#include "aws_nvmsgbroker.h" | ||||||||
#include <openssl/sha.h> | ||||||||
|
||||||||
NvDsMsgApiHandle (*nvds_msgapi_connect_ptr)(char *connection_str, nvds_msgapi_connect_cb_t connect_cb, char *config_path); | ||||||||
NvDsMsgApiErrorType (*nvds_msgapi_send_ptr)(NvDsMsgApiHandle conn, char *topic, const uint8_t *payload, size_t nbuf); | ||||||||
NvDsMsgApiErrorType (*nvds_msgapi_disconnect_ptr)(NvDsMsgApiHandle h_ptr); | ||||||||
NvDsMsgApiErrorType (*nvds_msgapi_connection_signature_ptr)(char *connection_str, char *config_path, char *output_str, int max_len); | ||||||||
static GMutex thread_mutex; | ||||||||
static GQueue *work_queue; | ||||||||
static struct timespec last_send_time_stamp; // this is to make sure we send or yield frequent enough so we do not get disconnected. | ||||||||
static struct timespec last_send_time_stamp; // this is to make sure we send or yield frequent enough so we do not get disconnected. | ||||||||
static nvds_msgapi_connect_cb_t disconnect_cb; // disconnect handler provided by connect thread | ||||||||
static nvds_msgapi_subscribe_request_cb_t nvds_cb; // msgapi subscribe callback handler | ||||||||
static char *subscribed_topics[MAX_SUBSCRIPTIONS]; // to store the subscribed topics in order to be used during unsubscribe operation | ||||||||
static size_t num_subscriptions = 0; // number of registered subscriptions | ||||||||
|
||||||||
/* ************************************************************************* */ | ||||||||
// Connect function def | ||||||||
/* ************************************************************************* */ | ||||||||
|
||||||||
static void disconnectCallbackHandler(AWS_IoT_Client *pClient, void *data) | ||||||||
static void | ||||||||
disconnectCallbackHandler(AWS_IoT_Client *pClient, void *data) | ||||||||
{ | ||||||||
IOT_WARN("MQTT Disconnect"); | ||||||||
IoT_Error_t rc = FAILURE; | ||||||||
|
@@ -83,7 +89,7 @@ NvDsMsgApiHandle nvds_msgapi_connect(char *connection_str, nvds_msgapi_connect_c | |||||||
disconnect_cb = connect_cb; | ||||||||
if (config_path == NULL) | ||||||||
{ | ||||||||
IOT_ERROR("Essensial args missing for function nvds_msgapi_connect\n"); | ||||||||
IOT_ERROR("Essential args missing for function nvds_msgapi_connect\n"); | ||||||||
return NULL; | ||||||||
} | ||||||||
|
||||||||
|
@@ -142,11 +148,21 @@ NvDsMsgApiErrorType nvds_msgapi_disconnect(NvDsMsgApiHandle h_ptr) | |||||||
{ | ||||||||
if ((h_ptr == NULL)) | ||||||||
{ | ||||||||
IOT_ERROR("Essensial args missing for function nvds_msgapi_disconnect\n"); | ||||||||
IOT_ERROR("Essential args missing for function nvds_msgapi_disconnect\n"); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
IoT_Error_t rc = FAILURE; | ||||||||
AWS_IoT_Client *client = (AWS_IoT_Client *)h_ptr; | ||||||||
for (int i = 0; i < num_subscriptions; i++) | ||||||||
{ | ||||||||
rc = aws_iot_mqtt_unsubscribe(client, subscribed_topics[i], strlen(subscribed_topics[i])); | ||||||||
if (SUCCESS != rc) | ||||||||
{ | ||||||||
IOT_ERROR("Unable to unsubscribe, error: %d\n", rc); | ||||||||
} | ||||||||
} | ||||||||
IOT_INFO("Successfully unsubscribed"); | ||||||||
|
||||||||
rc = aws_iot_mqtt_disconnect(client); | ||||||||
if (SUCCESS != rc) | ||||||||
{ | ||||||||
|
@@ -180,7 +196,7 @@ NvDsMsgApiErrorType nvds_msgapi_send(NvDsMsgApiHandle conn, char *topic, const u | |||||||
{ | ||||||||
if ((conn == NULL) || (topic == NULL) || (payload == NULL) || (nbuf == 0)) | ||||||||
{ | ||||||||
IOT_ERROR("Essensial args missing for function nvds_msgapi_send\n"); | ||||||||
IOT_ERROR("Essential args missing for function nvds_msgapi_send\n"); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
AWS_IoT_Client *client = (AWS_IoT_Client *)conn; | ||||||||
|
@@ -217,7 +233,7 @@ NvDsMsgApiErrorType nvds_msgapi_send_async(NvDsMsgApiHandle h_ptr, char *topic, | |||||||
{ | ||||||||
if ((h_ptr == NULL) || (topic == NULL) || (payload == NULL) || (nbuf == 0)) | ||||||||
{ | ||||||||
IOT_ERROR("Essensial args missing for function nvds_msgapi_send: %d, %d, %d, %d\n", (h_ptr == NULL), (topic == NULL), (payload == NULL), (nbuf == 0)); | ||||||||
IOT_ERROR("Essential args missing for function nvds_msgapi_send: %d, %d, %d, %d\n", (h_ptr == NULL), (topic == NULL), (payload == NULL), (nbuf == 0)); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
Work *work_node = g_malloc(sizeof(Work)); | ||||||||
|
@@ -243,6 +259,43 @@ NvDsMsgApiErrorType nvds_msgapi_send_async(NvDsMsgApiHandle h_ptr, char *topic, | |||||||
return NVDS_MSGAPI_OK; | ||||||||
} | ||||||||
|
||||||||
void nvds_cb_wrapped(AWS_IoT_Client *pClient, char *pTopicName, uint16_t topicNameLen, IoT_Publish_Message_Params *pParams, void *pClientData) | ||||||||
{ | ||||||||
IOT_INFO("Subscribe callback"); | ||||||||
nvds_cb(NVDS_MSGAPI_OK, pParams->payload, pParams->payloadLen, pTopicName, pClientData); | ||||||||
} | ||||||||
|
||||||||
NvDsMsgApiErrorType nvds_msgapi_subscribe(NvDsMsgApiHandle h_ptr, char **topics, int num_topics, nvds_msgapi_subscribe_request_cb_t cb, void *user_ctx) | ||||||||
{ | ||||||||
IOT_INFO("Subscribe called\n"); | ||||||||
if ((h_ptr == NULL) || (topics == NULL) || (num_topics <= 0)) | ||||||||
{ | ||||||||
IOT_ERROR("Essential args missing for function nvds_msgapi_subscribe: %d, %d, %d\n", (h_ptr == NULL), (topics == NULL), (num_topics == 0)); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
if (!cb) | ||||||||
{ | ||||||||
IOT_ERROR("Callback function for nvds_msgapi_subscribe cannot be NULL\n"); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
nvds_cb = cb; | ||||||||
IoT_Error_t rc = FAILURE; | ||||||||
AWS_IoT_Client *client = (AWS_IoT_Client *)h_ptr; | ||||||||
for (int i = 0; i < num_topics; i++) | ||||||||
{ | ||||||||
rc = aws_iot_mqtt_subscribe(client, topics[i], strlen(topics[i]), QOS0, nvds_cb_wrapped, user_ctx); | ||||||||
if (SUCCESS != rc) | ||||||||
{ | ||||||||
IOT_ERROR("Unable to subscribe, error: %d\n", rc); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
subscribed_topics[i] = topics[i]; | ||||||||
num_subscriptions++; | ||||||||
} | ||||||||
IOT_INFO("Successfully subscribed"); | ||||||||
return NVDS_MSGAPI_OK; | ||||||||
} | ||||||||
|
||||||||
/* ************************************************************************* */ | ||||||||
// Do Work function def | ||||||||
/* ************************************************************************* */ | ||||||||
|
@@ -277,7 +330,8 @@ void nvds_msgapi_do_work(NvDsMsgApiHandle h_ptr) | |||||||
} | ||||||||
return; | ||||||||
} | ||||||||
while (! g_queue_is_empty(work_queue)){ | ||||||||
while (!g_queue_is_empty(work_queue)) | ||||||||
{ | ||||||||
Work *work_node = (Work *)g_queue_pop_head(work_queue); | ||||||||
AWS_IoT_Client *client = (AWS_IoT_Client *)work_node->h_ptr; | ||||||||
rc = _mqtt_msg_send(client, work_node->topic, work_node->payload, work_node->payload_size); | ||||||||
|
@@ -291,7 +345,8 @@ void nvds_msgapi_do_work(NvDsMsgApiHandle h_ptr) | |||||||
g_free(work_node); | ||||||||
return; | ||||||||
} | ||||||||
if (work_node->call_back_handler != NULL){ | ||||||||
if (work_node->call_back_handler != NULL) | ||||||||
{ | ||||||||
IOT_INFO("Pointer callback."); | ||||||||
work_node->call_back_handler(work_node->user_ptr, NVDS_MSGAPI_OK); | ||||||||
} | ||||||||
|
@@ -300,3 +355,86 @@ void nvds_msgapi_do_work(NvDsMsgApiHandle h_ptr) | |||||||
last_send_time_stamp = current_time_stamp; | ||||||||
return; | ||||||||
} | ||||||||
|
||||||||
char *nvds_msgapi_getversion() | ||||||||
{ | ||||||||
return NVDS_MSGAPI_VERSION; | ||||||||
} | ||||||||
|
||||||||
char *nvds_msgapi_get_protocol_name() | ||||||||
{ | ||||||||
return NVDS_MSGAPI_PROTOCOL; | ||||||||
} | ||||||||
|
||||||||
bool is_valid_connection_str(char *connection_str) | ||||||||
{ | ||||||||
char *burl = "", *bport = ""; | ||||||||
if (connection_str == NULL) | ||||||||
{ | ||||||||
IOT_ERROR("connection string cant be NULL"); | ||||||||
return false; | ||||||||
} | ||||||||
|
||||||||
char conn_str[] = connection_str; | ||||||||
int i = 0; | ||||||||
|
||||||||
char *token = strtok(conn_str, ";"); | ||||||||
char *data[2]; | ||||||||
|
||||||||
while (token) | ||||||||
{ | ||||||||
data[i++] = token; | ||||||||
token = strtok(NULL, ";"); | ||||||||
} | ||||||||
for (i = 0; i < 2; i++) | ||||||||
{ | ||||||||
printf("%s\n", data[i]); | ||||||||
} | ||||||||
burl = data[0]; | ||||||||
bport = data[1]; | ||||||||
|
||||||||
if (burl == "" || bport == "") | ||||||||
{ | ||||||||
IOT_ERROR("connection string is invalid. hostname or port is empty\n"); | ||||||||
return false; | ||||||||
} | ||||||||
return true; | ||||||||
} | ||||||||
|
||||||||
char *generate_sha256_hash(char *str, char *output_str) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's typical in C-style APIs for the destination variable to come first. See There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, you're passing in this argument |
||||||||
{ | ||||||||
unsigned char hashval[SHA256_DIGEST_LENGTH]; | ||||||||
int len = SHA256_DIGEST_LENGTH * 2 + 1; | ||||||||
char res[len]; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To remedy the problem, you should supply the output string as an argument to the function. Note: it will need to have space for at least 65 characters (which you'll need to add a check for). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The max_len is actually the length of the output_str and I have added a check in the connection signature to check if has at least 65 characters There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good, but you still need to resolve the issue of returning a statically allocated variable. res is created on the stack, not the heap, so its lifetime is only that of the enclosing scope. The value of res will be invalidated once this function returns. |
||||||||
SHA256_CTX sha256; | ||||||||
SHA256_Init(&sha256); | ||||||||
SHA256_Update(&sha256, str, strlen(str)); | ||||||||
SHA256_Final(hashval, &sha256); | ||||||||
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) | ||||||||
{ | ||||||||
sprintf(res + (i * 2), "%02x", hashval[i]); | ||||||||
} | ||||||||
return res; | ||||||||
} | ||||||||
|
||||||||
NvDsMsgApiErrorType nvds_msgapi_connection_signature(char *broker_str, char *cfg, char *output_str, int max_len) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
{ | ||||||||
strcpy(output_str, ""); // Initializing output_str as empty string if successful which is updated later by SHA-256 hash else empty string is returned | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment isn't very helpful.
Suggested change
|
||||||||
int required_output_str_len = 2 * SHA256_DIGEST_LENGTH + 1 | ||||||||
if (broker_str == NULL || cfg == NULL) | ||||||||
{ | ||||||||
IOT_ERROR("nvds_msgapi_connection_signature: broker_str or cfg path cant be NULL\n"); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
if (max_len < required_output_str_len) | ||||||||
{ | ||||||||
IOT_ERROR("nvds_msgapi_connection_signature: insufficient output string length. Atleast %d needed", required_output_str_len); | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
if (!is_valid_connection_str(broker_str)) | ||||||||
{ | ||||||||
return NVDS_MSGAPI_ERR; | ||||||||
} | ||||||||
output_str = generate_sha256_hash(broker_str, output_str); | ||||||||
return NVDS_MSGAPI_OK; | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think this will work properly. The second call to
strtok
shouldn't give you a second token. Instead, try something like this: