Skip to content

Commit

Permalink
cami.c: Add ability to set/get custom callback data.
Browse files Browse the repository at this point in the history
  • Loading branch information
InterLinked1 committed Mar 29, 2024
1 parent ddf5217 commit b0a5b6c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 10 deletions.
1 change: 1 addition & 0 deletions amicli.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ int main(int argc,char *argv[])

ami = ami_connect(ami_host, 0, ami_callback, ami_disconnect_callback);
if (!ami) {
fprintf(stderr, "Failed to connect to %s\n", ami_host);
return -1;
}
ami_set_debug_level(ami, debug);
Expand Down
34 changes: 25 additions & 9 deletions cami.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct ami_session {
int ami_event_pipe[2]; /* Pipe for dispatching events to user callback functions */
void (*ami_callback)(struct ami_session *ami, struct ami_event *event);
void (*disconnected_callback)(struct ami_session *ami);
void *cb_data; /* User callback data */
int ami_msg_id;
int tx;
int rx;
Expand Down Expand Up @@ -209,7 +210,7 @@ static void *ami_loop(void *varg)

ami_debug(ami, 10, "Next chunk: %.*s ...\n", 18, nextevent);

starts_response = !strncmp(nextevent, "Response:", 9) ? 1 : 0;
starts_response = !strncmp(nextevent, "Response:", 9);
if (starts_response) {
ami_debug(ami, 7, "Got start of response... (%s)\n", nextevent);
/* If there's an EventList field, it's a multi-event response. If not, it's not. */
Expand All @@ -229,13 +230,14 @@ static void *ami_loop(void *varg)
middle_of_response = 1;
}
}
ami_debug(ami, 10, "Starts response: %d, middle of response: %d, ends response: %d\n", starts_response, middle_of_response, end_of_response);
/* Now, figure out what we should do. */
if (!starts_response && !middle_of_response) {
if (response_pending && !end_of_response) {
if (!starts_response && !middle_of_response && !end_of_response) {
if (response_pending) {
ami_error(ami, "BUG! Failed to detect end of response?\n");
}
/* This isn't an event that belongs to a response, including the start of one. It's just a regular unsolicited event. Send it now */
ami_debug(ami, 9, "Dispatching lone (unsolicited) event\n");
ami_debug(ami, 9, "Dispatching lone (unsolicited) event (%.*s ...)\n", 18, nextevent);
ami_event_handle(ami, laststart);
lasteventstart = laststart = endofevent;
event_pending = response_pending = 0;
Expand Down Expand Up @@ -277,18 +279,18 @@ static void *ami_loop(void *varg)

if (!event_pending && *nextevent) {
if (ami->debug_level >= 6) {
ami_warning(ami, " Empty line in event? (%s)\n", nextevent);
ami_debug(ami, 6, "Empty line in event? Probably incomplete... (%s)\n", nextevent);
} else {
ami_warning(ami, "Empty line in event?\n");
ami_debug(ami, 2, "Empty line in event? Probably incomplete...\n");
}
event_pending = 1;
} else if (!response_pending && !strncmp(nextevent, "Response:", 9)) {
/* In theory, not necessary? (covered by previous branch?) XXX Not so, because the above doesn't care about response_pending. */
/* Okay, what happened here was we weren't waiting for a response and suddenly we started one. */
if (ami->debug_level >= 6) {
ami_warning(ami, "Empty line in response event? (%s)\n", nextevent);
ami_debug(ami, 6, "Empty line in response event? Probably incomplete... (%s)\n", nextevent);
} else {
ami_warning(ami, "Empty line in response event?\n");
ami_debug(ami, 2, "Empty line in response event? Probably incomplete...\n");
}
response_pending = 1;
}
Expand Down Expand Up @@ -456,8 +458,22 @@ struct ami_session *ami_connect(const char *hostname, int port, void (*callback)
return NULL;
}

void ami_set_callback_data(struct ami_session *ami, void *data)
{
ami->cb_data = data;
}

void *ami_get_callback_data(struct ami_session *ami)
{
return ami->cb_data;
}

int ami_disconnect(struct ami_session *ami)
{
if (!ami) {
ami_error(ami, "ami_disconnect called with NULL session\n");
return -1;
}
if (ami->ami_socket < 0) {
return -1;
}
Expand Down Expand Up @@ -791,7 +807,7 @@ static void *ami_event_dispatch(void *varg)
char *start, *end;
res = read(ami->ami_event_pipe[0], buf, AMI_BUFFER_SIZE - 1);
if (res < 1) {
ami_warning(ami, "read pipe failed?\n");
ami_warning(ami, "Failed to read from read pipe (%d): %s\n", res, strerror(errno));
break;
}
/* Be prepared to receive multiple events, or not even a complete one. */
Expand Down
17 changes: 16 additions & 1 deletion include/cami.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#define CAMI_VERSION_MAJOR 0
#define CAMI_VERSION_MINOR 2
#define CAMI_VERSION_PATCH 0
#define CAMI_VERSION_PATCH 1

/* Max wait time in ms. Don't be tempted to make this too big, as this blocks all AMI traffic. Most of the time, it shouldn't really matter though. */
#define AMI_MAX_WAIT_TIME 1000
Expand Down Expand Up @@ -58,6 +58,7 @@ void ami_set_debug(struct ami_session *ami, int fd);

/*!
* \brief Set debug logging level
* \param ami
* \param level Level between 0 and 10. 0 will disable logging, 10 is the most granular. Default is 0.
* \note A log level of 1 is recommended for production use: this will log all errors and warnings. Use a greater log level for debugging.
* \retval -1 on failure, non-negative old log level otherwise
Expand All @@ -75,6 +76,20 @@ int ami_set_debug_level(struct ami_session *ami, int level);
*/
struct ami_session *ami_connect(const char *hostname, int port, void (*callback)(struct ami_session *ami, struct ami_event *event), void (*dis_callback)(struct ami_session *ami));

/*!
* \brief Set callback data
* \param ami
* \param data
*/
void ami_set_callback_data(struct ami_session *ami, void *data);

/*!
* \brief Retrieve callback data
* |param ami
* \return Callback data
*/
void *ami_get_callback_data(struct ami_session *ami);

/*!
* \brief Close an existing AMI connection
* \param ami
Expand Down

0 comments on commit b0a5b6c

Please sign in to comment.