Added the CodeBlocks project used to develop the Gadget Bridge parser code

This commit is contained in:
Th3maz1ng 2023-04-10 10:07:57 +02:00
parent 3bd772837c
commit f4ffc96d5a
6 changed files with 2026 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,220 @@
/**
* @file gadget_bridge.h
* @author Anatole SCHRAMM-HENRY
* @brief Header file exposing the API used to communicate/interact with the GadgetBridge Android application
* over BLE.
* @version 0.1
* @date 2023-04-04
*
* @copyright MIT
*
*/
#ifndef GADGET_BRIDGE_H
#define GADGET_BRIDGE_H
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
/**
* @brief Size of the internal buffer used to store incoming data
* which needs to be parsed.
*
*/
#define GADGET_BRIDGE_PARSER_BUFFER_SIZE (300)
#define GADGET_BRIDGE_PARSER_BUFFER_THRESHOLD (100)
#define GADGET_BRIDGE_PARSER_MAX_BODY_SIZE (200)
#define GADGET_BRIDGE_PARSER_MAX_TITLE_SIZE (100)
typedef enum gadget_bridge_toast_type
{
GADGET_BRIDGE_TOAST_TYPE_INFO = 0,
GADGET_BRIDGE_TOAST_TYPE_WARN,
GADGET_BRIDGE_TOAST_TYPE_ERROR,
} gadget_bridge_toast_type_e;
typedef enum gadget_bridge_music_control
{
GADGET_BRIDGE_MUSIC_CONTROL_PLAY = 0,
GADGET_BRIDGE_MUSIC_CONTROL_PAUSE,
GADGET_BRIDGE_MUSIC_CONTROL_PLAYPAUSE,
GADGET_BRIDGE_MUSIC_CONTROL_NEXT,
GADGET_BRIDGE_MUSIC_CONTROL_PREVIOUS,
GADGET_BRIDGE_MUSIC_CONTROL_VOLUMEUP,
GADGET_BRIDGE_MUSIC_CONTROL_VOLUMEDOWN,
GADGET_BRIDGE_MUSIC_CONTROL_FORWARD,
GADGET_BRIDGE_MUSIC_CONTROL_REWIND,
} gadget_bridge_music_control_e;
typedef enum gadget_bridge_call_action
{
GADGET_BRIDGE_CALL_ACTION_ACCEPT = 0,
GADGET_BRIDGE_CALL_ACTION_END,
GADGET_BRIDGE_CALL_ACTION_INCOMING,
GADGET_BRIDGE_CALL_ACTION_OUTGOING,
GADGET_BRIDGE_CALL_ACTION_REJECT,
GADGET_BRIDGE_CALL_ACTION_START,
GADGET_BRIDGE_CALL_ACTION_IGNORE,
GADGET_BRIDGE_CALL_ACTION_UNKNOWN,
} gadget_bridge_call_action_e;
typedef enum gadget_bridge_notification_action
{
GADGET_BRIDGE_NOTIFICATION_ACTION_DISMISS = 0,
GADGET_BRIDGE_NOTIFICATION_ACTION_DISMISS_ALL,
GADGET_BRIDGE_NOTIFICATION_ACTION_OPEN,
GADGET_BRIDGE_NOTIFICATION_ACTION_MUTE,
GADGET_BRIDGE_NOTIFICATION_ACTION_REPLY,
} gadget_bridge_notification_action_e;
typedef enum gadget_bridge_http_request_method
{
GADGET_BRIDGE_HTTP_REQUEST_GET = 0,
GADGET_BRIDGE_HTTP_REQUEST_POST,
GADGET_BRIDGE_HTTP_REQUEST_HEAD,
GADGET_BRIDGE_HTTP_REQUEST_PUT,
GADGET_BRIDGE_HTTP_REQUEST_PATCH,
GADGET_BRIDGE_HTTP_REQUEST_DELETE,
} gadget_bridge_http_request_method_e;
typedef enum gadget_bridge_parser_code
{
GADGET_BRIDGE_PARSER_CODE_OK = 0,
GADGET_BRIDGE_PARSER_CODE_PARSING,
GADGET_BRIDGE_PARSER_CODE_BUFFER_FULL,
GADGET_BRIDGE_PARSER_CODE_DATA_TOO_LONG,
} gadget_bridge_parser_code_e;
typedef struct http_header
{
const char *key;
const char *value;
} http_header_t;
typedef enum gadget_bridge_event_type
{
GADGET_BRIDGE_EVENT_TYPE_NONE = 0,
GADGET_BRIDGE_EVENT_TYPE_SET_TIME,
GADGET_BRIDGE_EVENT_TYPE_NOTIFY,
GADGET_BRIDGE_EVENT_TYPE_CALL,
GADGET_BRIDGE_EVENT_TYPE_WEATHER,
GADGET_BRIDGE_EVENT_TYPE_FIND,
GADGET_BRIDGE_EVENT_TYPE_ACT,
GADGET_BRIDGE_EVENT_TYPE_MUSIC_INFO,
GADGET_BRIDGE_EVENT_TYPE_MUSIC_STATE,
GADGET_BRIDGE_EVENT_TYPE_UNKNOWN,
} gadget_bridge_event_type_e;
typedef enum gadget_bridge_notification_type
{
GADGET_BRIDGE_NOTIFICATION_TYPE_SMS = 0,
GADGET_BRIDGE_NOTIFICATION_TYPE_EMAIL,
GADGET_BRIDGE_NOTIFICATION_TYPE_UNKNOWN,
} gadget_bridge_notification_type_e;
typedef enum
{
GADGET_BRIDGE_MUSIC_STATE_PAUSE = 0,
GADGET_BRIDGE_MUSIC_STATE_PLAY,
GADGET_BRIDGE_MUSIC_STATE_UNKNOWN,
} gadget_bridge_music_state_e;
typedef struct gadget_bridge_event_data
{
gadget_bridge_event_type_e event_type;
union
{
struct
{
struct tm gm_time;
struct tm local_time;
int8_t time_zone;
} time;
struct
{
uint32_t handle;
gadget_bridge_notification_type_e notification_type;
char *title;
char *body;
} notification;
struct
{
char *phone_number;
char *contact;
gadget_bridge_call_action_e call_action;
} call;
struct
{
float temperature_celsius;
uint8_t humidity;
char *weather_desc;
float wind_speed_kmh;
uint16_t wind_dir;
char *location;
} weather;
struct
{
bool find;
} find;
struct
{
bool heart_rate_monitor;
bool steps;
uint8_t heart_rate_interval;
} act;
struct
{
gadget_bridge_music_state_e music_state;
uint16_t position_in_seconds;
uint8_t shuffle;
uint8_t repeat;
} music_state;
struct
{
char *artist;
char *track;
uint16_t duration_in_seconds;
} music_info;
};
} gadget_bridge_event_data_t;
typedef void (*parser_event_callback_t)(const gadget_bridge_event_data_t *gadget_bridge_event_data);
bool gadget_bridge_send_toast(gadget_bridge_toast_type_e toast_type, const char *message);
bool gadget_bridge_send_firmware_version(const char *fw1, const char *fw2);
bool gadget_bridge_send_battery_status(uint8_t battery_level_in_percent, float battery_level_in_V, bool is_charging);
bool gadget_bridge_send_find_phone(bool find_phone);
bool gadget_bridge_send_music_control(gadget_bridge_music_control_e music_control);
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);
bool gadget_bridge_send_activity_data(uint16_t heart_rate_in_bpm, uint32_t step_count);
bool gadget_bridge_send_http_request(uint32_t id, const char *url, gadget_bridge_http_request_method_e http_request_method, const char *http_body, const http_header_t *http_headers);
void gadget_bridge_parser_register_event_callback(parser_event_callback_t parser_event_callback);
gadget_bridge_parser_code_e gadget_bridge_parser_feed(const char *data, uint16_t length);
gadget_bridge_parser_code_e gadget_bridge_parser_run(void);
const char *gadget_bridge_parser_code_2_str(gadget_bridge_parser_code_e parser_code);
const char *gadget_bridge_event_type_2_str(gadget_bridge_event_type_e event_type);
const char *gadget_bridge_notification_type_2_str(gadget_bridge_notification_type_e notification_type);
const char *gadget_bridge_music_state_2_str(gadget_bridge_music_state_e music_state);
void gadget_bridge_parser_debug(void);
#endif //GADGET_BRIDGE_H

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="gadget_bridge_parser" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/gadget_bridge_parser" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/gadget_bridge_parser" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Unit filename="gadget_bridge.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="gadget_bridge.h" />
<Unit filename="main.c">
<Option compilerVar="CC" />
</Unit>
<Extensions />
</Project>
</CodeBlocks_project_file>

View File

@ -0,0 +1,18 @@
# depslib dependency file v1.0
1681050439 source:/home/think/Desktop/Mes_documents/Programming/C_C++/gadget_bridge_parser/main.c
<stdio.h>
<stdlib.h>
<string.h>
"gadget_bridge.h"
1681050803 source:/home/think/Desktop/Mes_documents/Programming/C_C++/gadget_bridge_parser/gadget_bridge.c
"gadget_bridge.h"
<stdio.h>
<stdlib.h>
<string.h>
1681049124 /home/think/Desktop/Mes_documents/Programming/C_C++/gadget_bridge_parser/gadget_bridge.h
<stdint.h>
<stdbool.h>
<time.h>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<FileVersion major="1" minor="0" />
<ActiveTarget name="Debug" />
<File name="gadget_bridge.c" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="252" topLine="0" />
</Cursor>
</File>
<File name="gadget_bridge.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="0" />
</Cursor>
</File>
<File name="main.c" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="168" topLine="108" />
</Cursor>
</File>
</CodeBlocks_layout_file>

View File

@ -0,0 +1,308 @@
/**
* @file main.c
* @author Anatole SCHRAMM-HENRY
* @brief Source file containing the test programm used to verify the parser
*
* @version 0.1
* @date 2023-04-10
*
* @copyright MIT
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gadget_bridge.h"
/**
[3][16]setTime(1680860758);E.setTimeZone(2.0);(s=>{s&&(s.timezone=2.0)&&require('Storage').write('setting.json',s);})(require('Storage').readJSON('setting.json',1))
[10][16]GB({t:"calendar",id:63751,type:0,timestamp:1680991200,durationInSeconds:86400,title:"Easter Sunday",description:"Observance\nTo hide observances, go to Google Calendar Settings > Holidays in France",location:"",calName:"anatole.schramm-henry@master-stic.fr/Holidays in France",color:-15292571,allDay:true})
[10][16]GB({t:"calendar",id:63749,type:0,timestamp:1681077600,durationInSeconds:86400,title:"Easter Monday",description:"Public holiday",location:"",calName:"anatole.schramm-henry@master-stic.fr/Holidays in France",color:-15292571,allDay:true})
[10][16]GB({t:"weather",temp:0,hum:0,code:3200,wind:0.0,wdir:0,loc:""})[10]
[16]GB({t:"notify",id:1680859061,body:"test hehe test",sender:"+33652623698",tel:"+33652623698"})
[10][16]GB({t:"notify",id:1680859062,src:"Messages",title:"06 52 62 36 98",body:"test hehe test"})[10]
[16]GB({t:"notify",id:1680859063,src:"E-mail",title:"Th3maz1ng Wot Channel",body:"Test subject"})[10]
[16]GB({t:"call",cmd:"incoming",name:"+33950208629",number:"+33950208629"})
[10][16]GB({t:"call",cmd:"end",name:"+33950208629",number:"+33950208629"})[10]
[16]GB({t:"weather",temp:284,hum:89,code:803,txt:"nuages mod⸮r⸮s",wind:11.0,wdir:347,loc:"ST. ETIENNE"})[10]
[16]GB({t:"weather",temp:284,hum:89,code:803,txt:"nuages mod⸮r⸮s",wind:11.0,wdir:347,loc:"ST. ETIENNE"})[10]
GB({t:"find",n:true})[10]
[16]GB({t:"find",n:false})[10]
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)
{
printf("----------->Event of type : %s\n", gadget_bridge_event_type_2_str(gadget_bridge_event_data->event_type));
switch(gadget_bridge_event_data->event_type)
{
case GADGET_BRIDGE_EVENT_TYPE_SET_TIME:
printf("%d:%d:%d %d/%d/%d\n%d\n",
gadget_bridge_event_data->time.local_time.tm_hour,
gadget_bridge_event_data->time.local_time.tm_min,
gadget_bridge_event_data->time.local_time.tm_sec,
gadget_bridge_event_data->time.local_time.tm_mday,
gadget_bridge_event_data->time.local_time.tm_mon,
gadget_bridge_event_data->time.local_time.tm_year + 1900,
gadget_bridge_event_data->time.time_zone);
break;
case GADGET_BRIDGE_EVENT_TYPE_NOTIFY:
printf("%u\n%s\n%s\n%s\n",
gadget_bridge_event_data->notification.handle,
gadget_bridge_notification_type_2_str(gadget_bridge_event_data->notification.notification_type),
gadget_bridge_event_data->notification.title,
gadget_bridge_event_data->notification.body);
break;
break;
case GADGET_BRIDGE_EVENT_TYPE_CALL:
printf("%u\n%s\n%s\n",
gadget_bridge_event_data->call.call_action,
gadget_bridge_event_data->call.contact,
gadget_bridge_event_data->call.phone_number);
break;
case GADGET_BRIDGE_EVENT_TYPE_WEATHER:
printf("%.2f\n%u\n%s\n%.2f\n%u\n%s\n",
gadget_bridge_event_data->weather.temperature_celsius,
gadget_bridge_event_data->weather.humidity,
gadget_bridge_event_data->weather.weather_desc,
gadget_bridge_event_data->weather.wind_speed_kmh,
gadget_bridge_event_data->weather.wind_dir,
gadget_bridge_event_data->weather.location);
break;
case GADGET_BRIDGE_EVENT_TYPE_FIND:
printf("%d\n",gadget_bridge_event_data->find.find);
break;
case GADGET_BRIDGE_EVENT_TYPE_ACT:
printf("%d\n%d\n%u\n",
gadget_bridge_event_data->act.heart_rate_monitor,
gadget_bridge_event_data->act.steps,
gadget_bridge_event_data->act.heart_rate_interval);
break;
case GADGET_BRIDGE_EVENT_TYPE_MUSIC_STATE:
printf("%s\n%u\n%u\n%u\n",
gadget_bridge_music_state_2_str(gadget_bridge_event_data->music_state.music_state),
gadget_bridge_event_data->music_state.position_in_seconds,
gadget_bridge_event_data->music_state.shuffle,
gadget_bridge_event_data->music_state.repeat);
break;
case GADGET_BRIDGE_EVENT_TYPE_MUSIC_INFO:
printf("%s\n%s\n%u\n",
gadget_bridge_event_data->music_info.artist,
gadget_bridge_event_data->music_info.track,
gadget_bridge_event_data->music_info.duration_in_seconds);
break;
default:
printf("Unhandled\n");
}
}
const char *sample[] =
{
"[3]",
"[16]setTime(1680979884)",
";E.setTimeZone(2.0);",
"(s=>{s&&(s.timezone=",
"2.0)&&require('Stora",
"ge').write('setting.",
"json',s);})(require(",
"'Storage').readJSON(",
"'setting.json',1))[10]",
"[16]GB({t:\"calendar\",id",
":63992,type:0,timest",
"amp:1680991200,durat",
"ionInSeconds:86400,t",
"itle:\"Easter Sunday\"",
",description:\"Observ",
"ance\nTo hide observ",
"ances, go to Google ",
"Calendar Settings > ",
"Holidays in France\",",
"location:\"\",calName:",
"\"anatole.schramm-hen",
"ry@master-stic.fr/Ho",
"lidays in France\",co",
"lor:-15292571,allDay",
":true})[10]",
"[16]GB({t:\"calendar\",id",
":63990,type:0,timest",
"amp:1681077600,durat",
"ionInSeconds:86400,t",
"itle:\"Easter Monday\"",
",description:\"Public",
" holiday\",location:\"",
"\",calName:\"anatole.s",
"chramm-henry@master-",
"stic.fr/Holidays in ",
"France\",color:-15292",
"571,allDay:true})[10]",
"[16]GB({t:\"act\",hrm:fal",
"se,stp:true,int:10})",
"[10]",
"[16]GB({t:\"act\",hrm:tru",
"e,stp:true,int:10})[10]",
"[16]GB({t:\"act\",hrm:tru",
"e,stp:false,int:10})",
"[10]",
"[16]GB({t:\"act\",hrm:fal",
"se,stp:false,int:10}",
")[10]",
"[16]GB({t:\"find\",n:true",
"})[10]",
"[16]GB({t:\"find\",n:fals",
"e})[10]",
"[16]GB({t:\"find\",n:fals",
"e})[10]",
"[16]GB({t:\"weather\",tem",
"p:277,hum:96,code:80",
"4,txt:\"tr⸮s nuageux\"",
",wind:4.0,wdir:130,l",
"oc:\"ST. ETIENNE\"})[10]",
"[16]GB({t:\"notify\",id:1",
"680945578,body:\"test",
" 1 2 1 2\",sender:\"+3",
"3652623698\",tel:\"+33",
"652623698\"})[10]",
"[16]GB({t:\"notify\",id:1",
"680945579,src:\"Messa",
"ges\",title:\"06 52 62",
" 36 98\",body:\"test 1",
" 2 1 2\"})[10]",
"[16]GB({t:\"notify\",id:1",
"6809533,src:\"Messa",
"ges\",title:\"06 52 62",
" 36 98\",body:\"test 2",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
" lol xptdr\"})[10]",
"[16]GB({t:\"call\",cm",
"d:\"incoming\",nam",
"e:\"+3395020862",
"9\",number:\"+33950208",
"629\"})",
"[16]GB({t:\"call\",cm",
"d:\"end\",nam",
"e:\"+3395020862",
"9\",number:\"+33950208",
"629\"})",
"[16]GB({t:\"notify\",id",
":1680859063,src:\"E-mail",
"\",title:\"Th3maz1ng Wo",
"qsfsqfqsfagueule",
"et ce txcbxcbcxbxccxbcxcbcbeule",
"et ce txvvxcvcxvbnbv,jkmlgueule",
"et ce titre estcvbcnvcnghjhjhgjghueule",
"et ce titre ewcwxcxwcxwc magueule",
"t Channel\",body:\"Test",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
"Lorem ipsum dolor sit ",
" subject\"})[10]",
"[16]GB({t:\"notify\",id",
":1680859063,src:\"E-mail",
"\",title:\"Th3maz1ng Wo",
"t Channel\",body:\"Test",
" subject\"})[10]",
"[16]GB({t:\"musicinfo\",a",
"rtist:\"The Good Life",
" Radio x Sensual Mus",
"ique\",track:\"The Goo",
"d Life Radio⸮?⸮24/7 ",
"Live Radio | Best Re",
"lax House, Chillout,",
" Study, Running, Gym",
", Happy Music\",dur:0",
",c:-1,n:-1})[10]",
"[16]GB({t:\"musicstate\",",
"state:\"pause\",positi",
"on:3587,shuffle:1,re",
"peat:1})[10]",
"[16]GB({t:\"musicinfo\",a",
"rtist:\"The Good Life",
" Radio x Sensual Mus",
"ique\",track:\"The Goo",
"d Life Radio⸮?⸮24/7 ",
"Live Radio | Best Re",
"lax House, Chillout,",
" Study, Running, Gym",
", Happy Music\",dur:0",
",c:-1,n:-1})[10]",
"[16]GB({t:\"musicstate\",",
"state:\"play\",positio",
"n:3582,shuffle:1,rep",
"eat:1})[10]",
"[16]GB({t:\"musicinfo\",a",
"rtist:\"Bliss Corpora",
"tion\",track:\"Eiffel ",
"65 - Blue (Da Ba Dee",
") [Gabry Ponte Ice P",
"op Mix] (Original Vi",
"deo with subtitles)\"",
",dur:219,c:-1,n:-1})",
};
int main()
{
gadget_bridge_parser_code_e code;
printf("Testing the gadget bridge parser :\n");
gadget_bridge_parser_register_event_callback(&(parser_event));
uint8_t sample_count = sizeof sample / sizeof *sample;
printf("Number of samples : %u\n", sample_count);
for(uint8_t i = 0; i < sample_count; i++)
{
gadget_bridge_parser_feed(sample[i], strlen(sample[i]));
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();
}
return 0;
}