Updated the Gadget Bridge parser to parse debug frames needed when implementing the notification manager

This commit is contained in:
Th3maz1ng 2023-04-23 20:27:29 +02:00
parent e3321d67ab
commit b45c5fdcbf
4 changed files with 159 additions and 25 deletions

View File

@ -34,6 +34,9 @@ typedef enum gadget_bridge_parser_fsm
GADGET_BRIDGE_PARSER_FSM_FOUND_TITLE,
GADGET_BRIDGE_PARSER_FSM_PARSING_TITLE_CONTENT,
GADGET_BRIDGE_PARSER_FSM_FOUND_SUBJECT,
GADGET_BRIDGE_PARSER_FSM_PARSING_SUBJECT_BODY_CONTENT,
GADGET_BRIDGE_PARSER_FSM_FOUND_ID_SRC,
GADGET_BRIDGE_PARSER_FSM_FOUND_SRC_BODY,
GADGET_BRIDGE_PARSER_FSM_PARSING_BODY_CONTENT,
@ -239,7 +242,7 @@ static bool _parser_extract_bool(char *start, char *end, bool *data);
gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
{
if(!_gadget_bridge_internals.new_data) return GADGET_BRIDGE_PARSER_CODE_OK;
char *start = NULL, *end = NULL;
char *start = NULL, *end = NULL, *end2 = NULL; // end2 is used when more than one next tag is possible
bool free_some_space = false;
gadget_bridge_parser_code_e to_return = GADGET_BRIDGE_PARSER_CODE_PARSING;
@ -419,10 +422,20 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
else to_return = GADGET_BRIDGE_PARSER_CODE_OK;
break;
case GADGET_BRIDGE_PARSER_FSM_FOUND_ID_SRC:
if((start = strstr(_gadget_bridge_internals.buffer, "src:"))
&& (end = strstr(_gadget_bridge_internals.buffer, ",title")))
if((start = strstr(_gadget_bridge_internals.buffer, "src:")) &&
((end = strstr(_gadget_bridge_internals.buffer, ",title")) || (end2 = strstr(_gadget_bridge_internals.buffer, ",subject"))))
{
printf("###Found TITLE\n");
if((end && !end2) || (end != NULL && end < end2))
{
printf("###Found TITLE\n");
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_FOUND_TITLE;
}
else if((!end && end2) || (end2 != NULL && end2 < end))
{
printf("###Found SUBJECT\n");
end = end2;
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_FOUND_SUBJECT;
}
_parser_extract_src(start + 5, end - 1);
@ -431,7 +444,6 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
_parser_free_buffer(
end -_gadget_bridge_internals.buffer
);
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_FOUND_TITLE;
}
else if((start = strstr(_gadget_bridge_internals.buffer, "GB(")))
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
@ -503,7 +515,11 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
_parser_free_buffer(
start -_gadget_bridge_internals.buffer
);
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_PARSING_BODY_CONTENT;
if(_gadget_bridge_internals.event_data.notification.notification_type == GADGET_BRIDGE_NOTIFICATION_TYPE_GADGET_BRIDGE)
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_PARSING_SUBJECT_BODY_CONTENT;
else
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_PARSING_BODY_CONTENT;
}
else if((start = strstr(_gadget_bridge_internals.buffer, "GB(")))
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
@ -567,6 +583,63 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
else to_return = GADGET_BRIDGE_PARSER_CODE_OK;
}
break;
case GADGET_BRIDGE_PARSER_FSM_PARSING_SUBJECT_BODY_CONTENT:
{
end = strstr(_gadget_bridge_internals.buffer, ",sender");
if(end)
{
// We don't care about the sender nor the tel tag
printf("###TEST NOTIFICATION Type done\n");
_parser_extract_char_str(_gadget_bridge_internals.buffer, end - 1, &_gadget_bridge_internals.event_data.notification.body);
// We remove the parsed part from the buffer
end += 7;
_parser_free_buffer(
end -_gadget_bridge_internals.buffer
);
// If a callback was registered, we call it and pass the data to it
if(_gadget_bridge_internals.parser_event_callback)
{
_gadget_bridge_internals.parser_event_callback(&_gadget_bridge_internals.event_data);
}
// Free the allocated data
_free_event_data();
// The end of the road for this object
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
}
else if((start = strstr(_gadget_bridge_internals.buffer, "GB(")))
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
// Then we have a very long body, in this case we juste keep the max set up
else if(!end && _gadget_bridge_internals.buffer_content_size >= GADGET_BRIDGE_PARSER_MAX_BODY_SIZE)
{
printf("###TEST NOTIFICATION (MAX BODY SIZE) Type done\n");
_parser_extract_char_str(_gadget_bridge_internals.buffer, _gadget_bridge_internals.buffer + GADGET_BRIDGE_PARSER_MAX_BODY_SIZE, &_gadget_bridge_internals.event_data.notification.body);
// We remove the parsed part from the buffer
_parser_free_buffer(
GADGET_BRIDGE_PARSER_MAX_BODY_SIZE + 1
);
// If a callback was registered, we call it and pass the data to it
if(_gadget_bridge_internals.parser_event_callback)
{
_gadget_bridge_internals.parser_event_callback(&_gadget_bridge_internals.event_data);
}
// Free the allocated data
_free_event_data();
// The end of the road for this object
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
}
else to_return = GADGET_BRIDGE_PARSER_CODE_OK;
}
break;
/*case GADGET_BRIDGE_PARSER_FSM_FOUND_ID_BODY:
if((start = strstr(_gadget_bridge_internals.buffer, "body:"))
&& (end = strstr(_gadget_bridge_internals.buffer, ",sender")))
@ -624,6 +697,24 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
break;*/
case GADGET_BRIDGE_PARSER_FSM_FOUND_SUBJECT:
if((start = strstr(_gadget_bridge_internals.buffer, "subject:")))
{
printf("###Parsing SUBJECT content\n");
// We remove the parsed part from the buffer
start += 9;
_parser_free_buffer(
start -_gadget_bridge_internals.buffer
);
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_PARSING_TITLE_CONTENT;
}
else if((start = strstr(_gadget_bridge_internals.buffer, "GB(")))
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
else if(_gadget_bridge_internals.buffer_content_size > GADGET_BRIDGE_PARSER_BUFFER_THRESHOLD)
free_some_space = true;
else to_return = GADGET_BRIDGE_PARSER_CODE_OK;
break;
case GADGET_BRIDGE_PARSER_FSM_FOUND_CALL:
if((start = strstr(_gadget_bridge_internals.buffer, "cmd:"))
&& (end = strstr(_gadget_bridge_internals.buffer, ",name")))
@ -1144,6 +1235,7 @@ const char *gadget_bridge_notification_type_2_str(gadget_bridge_notification_typ
{
CASE_RETURN_STR(GADGET_BRIDGE_NOTIFICATION_TYPE_SMS)
CASE_RETURN_STR(GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL)
CASE_RETURN_STR(GADGET_BRIDGE_NOTIFICATION_TYPE_GADGET_BRIDGE)
CASE_RETURN_STR(GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN)
default:
return "Unknown notification type";
@ -1319,6 +1411,8 @@ static void _parser_extract_src(char *start, char *end)
_gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_SMS;
else if(strcmp(start, "E-mail") == 0)
_gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL;
else if(strcmp(start, "Gadgetbridge") == 0)
_gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_GADGET_BRIDGE;
else
_gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN;

View File

@ -28,21 +28,21 @@
* @brief GADGET_BRIDGE_PARSER_BUFFER_THRESHOLD permits to set a size threshold used to free up
* some space in the parser's internal buffer when the threshold is reached.
* This ensures that we can keep on feeding new data and not get stuck.
*
*
*/
#define GADGET_BRIDGE_PARSER_BUFFER_THRESHOLD (100)
/**
* @brief GADGET_BRIDGE_PARSER_MAX_BODY_SIZE defines the max body size that will be saved in the event_data
* structure when parsing the body of a notification.
*
*
*/
#define GADGET_BRIDGE_PARSER_MAX_BODY_SIZE (200)
/**
* @brief GADGET_BRIDGE_PARSER_MAX_TITLE_SIZE defines the max title size that will be saved in the event_data
* structure when parsing the title of a notification.
*
*
*/
#define GADGET_BRIDGE_PARSER_MAX_TITLE_SIZE (100)
@ -130,6 +130,7 @@ typedef enum gadget_bridge_notification_type
{
GADGET_BRIDGE_NOTIFICATION_TYPE_SMS = 0,
GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL,
GADGET_BRIDGE_NOTIFICATION_TYPE_GADGET_BRIDGE,
GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN,
} gadget_bridge_notification_type_e;
@ -203,7 +204,7 @@ typedef void (*parser_event_callback_t)(const gadget_bridge_event_data_t *gadget
/**
* @brief Sends an Android toast to GadgetBridge to be displayed on the phone.
*
*
* @param toast_type the type of the toast (INFO, WARN or ERROR).
* @param message a string representing the message to display.
* @return true if the command was successfully sent.
@ -214,7 +215,7 @@ bool gadget_bridge_send_toast(gadget_bridge_toast_type_e toast_type, const char
/**
* @brief Sends up to two firmwares version to GadgetBridge.
* These are displayed in the display details section of the watch in GadgetBridge.
*
*
* @param fw1 a string representing the first firmware version.
* @param fw2 a string representing the second firmware version.
* @return true if the command was successfully sent.
@ -224,7 +225,7 @@ bool gadget_bridge_send_firmware_version(const char *fw1, const char *fw2);
/**
* @brief Sends the current battery status to GadgetBridge.
*
*
* @param battery_level_in_percent the current battery level from 0 to 100%.
* @param battery_level_in_V the current battery voltage in volts (3.942 for example).
* @param is_charging a boolean which indicates if the battery is currently charging or not.
@ -236,7 +237,7 @@ bool gadget_bridge_send_battery_status(uint8_t battery_level_in_percent, float b
/**
* @brief Sends the find phone command to GagdetBridge, this will make the phone ring and vibrate
* so that you can locate it.
*
*
* @param find_phone a boolean which indicates to make the phone rind and vibrate or not.
* @return true if the command was successfully sent.
* @return false otherwise.
@ -245,7 +246,7 @@ bool gadget_bridge_send_find_phone(bool find_phone);
/**
* @brief Sends a command to control the music playback of the phone through GadgetBridge.
*
*
* @param music_control an enumeration value indicating the action to perform:
* PLAY, PAUSE, NEXT, PREVIOUS, VOLUMEUP etc..
* @return true if the command was successfully sent.
@ -258,9 +259,9 @@ bool gadget_bridge_handle_call(gadget_bridge_call_action_e call_action);
bool gadget_bridge_handle_notification(gadget_bridge_call_action_e notification_action, uint32_t handle, const char *phone_number, const char *message);
/**
* @brief Sends the provided activity data to GadgetBridge. This will then be displayed
* @brief Sends the provided activity data to GadgetBridge. This will then be displayed
* on the app in the activity section.
*
*
* @param heart_rate_in_bpm the current heart rate in beat per minute
* @param step_count the number of new steps since the last time the count was sent.
* @return true if the command was successfully sent.
@ -271,7 +272,7 @@ bool gadget_bridge_send_activity_data(uint16_t heart_rate_in_bpm, uint32_t step_
/**
* @brief Tells GadgetBridge to perform an HTTP request for us.
* @note THIS DOES NOT WORK as GadgetBridge don't and will never have network permission... what a pitty !
*
*
* @param id an unsigned integer representing the ID of the http request
* @param url a string representing the URL to fetch
* @param http_request_method a enumeration value specifying the http verb to use : GET, POST, PATCH etc..
@ -286,14 +287,14 @@ bool gadget_bridge_send_http_request(uint32_t id, const char *url, gadget_bridge
/**
* @brief Registers a callback function used to listen for GadgetBridge events.
*
* @param parser_event_callback
*
* @param parser_event_callback
*/
void gadget_bridge_parser_register_event_callback(parser_event_callback_t parser_event_callback);
/**
* @brief Feeds new data to the GadgetBridge parser.
*
*
* @param data the new chunk of data to parse, it will be copied to the parser's internal buffer,
* so you can free the memory containing the string after calling the function.
* @param length the length in bytes of the new chunk.
@ -304,7 +305,7 @@ gadget_bridge_parser_code_e gadget_bridge_parser_feed(const char *data, uint16_t
/**
* @brief Call this function to run the parser.
* It should be safe to call if in a loop like : while((code = gadget_bridge_parser_run()) == GADGET_BRIDGE_PARSER_CODE_PARSING);
*
*
* @return gadget_bridge_parser_code_e the parser's execution status code.
*/
gadget_bridge_parser_code_e gadget_bridge_parser_run(void);

View File

@ -33,3 +33,20 @@
<string.h>
"gadget_bridge.h"
1682237814 source:/home/think/Desktop/Mes_documents/Programming/C_C++/W800_Smart_Watch/src/gadget_bridge_parser/main.c
<stdio.h>
<stdlib.h>
<string.h>
"gadget_bridge.h"
1682233727 /home/think/Desktop/Mes_documents/Programming/C_C++/W800_Smart_Watch/src/gadget_bridge_parser/gadget_bridge.h
<stdint.h>
<stdbool.h>
<time.h>
1682237962 source:/home/think/Desktop/Mes_documents/Programming/C_C++/W800_Smart_Watch/src/gadget_bridge_parser/gadget_bridge.c
"gadget_bridge.h"
<stdio.h>
<stdlib.h>
<string.h>

View File

@ -37,8 +37,6 @@ GB({t:"act",hrm:false,stp:true,int:10})[10]
[16]GB({t:"act",hrm:true,stp:true,int:10})[10]
[16]GB({t:"act",hrm:true,stp:false,int:10})[10]
[16]GB({t:"act",hrm:false,stp:false,int:10})[10]
Add time zone
**/
void parser_event(const gadget_bridge_event_data_t *gadget_bridge_event_data)
@ -294,6 +292,30 @@ const char *sample[] =
"sender :\"This is a test",
"payload \",tel:\"This is",
" a test payload \"})[10]",
"[16]GB({t:\"notify\",id:",
"1682154002,src:\"Gadgetb",
"ridge\",subject:\"This i",
"s a test payload with a ",
"pretty long text because",
" it has to be also teste",
"d, we never know if some",
"thing was badly design",
"e\",body:\"",
"This is a test payload w",
"ith a very long content ",
"to make sure this case i",
"s handled in the parser ",
"and we do not crash the ",
"thing because we forgot ",
"to handle such a case, d",
"on't you think ? I need ",
"some more text apparentl",
"y as what I Wrote still ",
"isn't enough\",",
"sender :\"This is a test",
"payload \",tel:\"This is",
" a test payload \"})[10]",
};
int main()
@ -311,10 +333,10 @@ int main()
{
gadget_bridge_parser_feed(sample[i], strlen(sample[i]));
gadget_bridge_parser_debug();
//gadget_bridge_parser_debug();
while((code = gadget_bridge_parser_run()) == GADGET_BRIDGE_PARSER_CODE_PARSING);
printf("Parser code : %s\n", gadget_bridge_parser_code_2_str(code));
gadget_bridge_parser_debug();
//gadget_bridge_parser_debug();
}
return 0;