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_FOUND_TITLE,
GADGET_BRIDGE_PARSER_FSM_PARSING_TITLE_CONTENT, 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_ID_SRC,
GADGET_BRIDGE_PARSER_FSM_FOUND_SRC_BODY, GADGET_BRIDGE_PARSER_FSM_FOUND_SRC_BODY,
GADGET_BRIDGE_PARSER_FSM_PARSING_BODY_CONTENT, 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) gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
{ {
if(!_gadget_bridge_internals.new_data) return GADGET_BRIDGE_PARSER_CODE_OK; 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; bool free_some_space = false;
gadget_bridge_parser_code_e to_return = GADGET_BRIDGE_PARSER_CODE_PARSING; 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; else to_return = GADGET_BRIDGE_PARSER_CODE_OK;
break; break;
case GADGET_BRIDGE_PARSER_FSM_FOUND_ID_SRC: case GADGET_BRIDGE_PARSER_FSM_FOUND_ID_SRC:
if((start = strstr(_gadget_bridge_internals.buffer, "src:")) if((start = strstr(_gadget_bridge_internals.buffer, "src:")) &&
&& (end = strstr(_gadget_bridge_internals.buffer, ",title"))) ((end = strstr(_gadget_bridge_internals.buffer, ",title")) || (end2 = strstr(_gadget_bridge_internals.buffer, ",subject"))))
{
if((end && !end2) || (end != NULL && end < end2))
{ {
printf("###Found TITLE\n"); 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); _parser_extract_src(start + 5, end - 1);
@ -431,7 +444,6 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
_parser_free_buffer( _parser_free_buffer(
end -_gadget_bridge_internals.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("))) else if((start = strstr(_gadget_bridge_internals.buffer, "GB(")))
_gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE; _gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
@ -503,6 +515,10 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
_parser_free_buffer( _parser_free_buffer(
start -_gadget_bridge_internals.buffer start -_gadget_bridge_internals.buffer
); );
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; _gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_PARSING_BODY_CONTENT;
} }
else if((start = strstr(_gadget_bridge_internals.buffer, "GB("))) else if((start = strstr(_gadget_bridge_internals.buffer, "GB(")))
@ -567,6 +583,63 @@ gadget_bridge_parser_code_e gadget_bridge_parser_run(void)
else to_return = GADGET_BRIDGE_PARSER_CODE_OK; else to_return = GADGET_BRIDGE_PARSER_CODE_OK;
} }
break; 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: /*case GADGET_BRIDGE_PARSER_FSM_FOUND_ID_BODY:
if((start = strstr(_gadget_bridge_internals.buffer, "body:")) if((start = strstr(_gadget_bridge_internals.buffer, "body:"))
&& (end = strstr(_gadget_bridge_internals.buffer, ",sender"))) && (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; _gadget_bridge_internals.gadget_bridge_parser_fsm = GADGET_BRIDGE_PARSER_FSM_NEW_MESSAGE;
break;*/ 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: case GADGET_BRIDGE_PARSER_FSM_FOUND_CALL:
if((start = strstr(_gadget_bridge_internals.buffer, "cmd:")) if((start = strstr(_gadget_bridge_internals.buffer, "cmd:"))
&& (end = strstr(_gadget_bridge_internals.buffer, ",name"))) && (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_SMS)
CASE_RETURN_STR(GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL) 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) CASE_RETURN_STR(GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN)
default: default:
return "Unknown notification type"; 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; _gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_SMS;
else if(strcmp(start, "E-mail") == 0) else if(strcmp(start, "E-mail") == 0)
_gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL; _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 else
_gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN; _gadget_bridge_internals.event_data.notification.notification_type = GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN;

View File

@ -130,6 +130,7 @@ typedef enum gadget_bridge_notification_type
{ {
GADGET_BRIDGE_NOTIFICATION_TYPE_SMS = 0, GADGET_BRIDGE_NOTIFICATION_TYPE_SMS = 0,
GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL, GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL,
GADGET_BRIDGE_NOTIFICATION_TYPE_GADGET_BRIDGE,
GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN, GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN,
} gadget_bridge_notification_type_e; } gadget_bridge_notification_type_e;

View File

@ -33,3 +33,20 @@
<string.h> <string.h>
"gadget_bridge.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:true,int:10})[10]
[16]GB({t:"act",hrm:true,stp:false,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] [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) 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", "sender :\"This is a test",
"payload \",tel:\"This is", "payload \",tel:\"This is",
" a test payload \"})[10]", " 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() int main()
@ -311,10 +333,10 @@ int main()
{ {
gadget_bridge_parser_feed(sample[i], strlen(sample[i])); 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); while((code = gadget_bridge_parser_run()) == GADGET_BRIDGE_PARSER_CODE_PARSING);
printf("Parser code : %s\n", gadget_bridge_parser_code_2_str(code)); printf("Parser code : %s\n", gadget_bridge_parser_code_2_str(code));
gadget_bridge_parser_debug(); //gadget_bridge_parser_debug();
} }
return 0; return 0;