Implemented the gadget_bridge parser feature as well as a few commands like the music control or the find device phone feature

This commit is contained in:
Th3maz1ng 2023-04-08 22:43:52 +02:00
parent a9e5589e87
commit e71c020d97
3 changed files with 1250 additions and 25 deletions

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,15 @@
#define GADGET_BRIDGE_H
#include "wm_type_def.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)
typedef enum gadget_bridge_toast_type
{
@ -44,6 +53,7 @@ typedef enum gadget_bridge_call_action
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
@ -66,17 +76,92 @@ typedef enum gadget_bridge_http_request_method
} 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_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 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;
};
} 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_mV, bool is_charging);
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);
@ -84,10 +169,24 @@ bool gadget_bridge_send_music_control(gadget_bridge_music_control_e music_contro
bool gadget_bridge_handle_call(gadget_bridge_call_action_e call_action);
bool gadget_bridge_handle_notification(gadget_bridge_call_action_e notification_action, uint64_t handle, const char *phone_number, const char *message);
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);
#endif //GADGET_BRIDGE_H
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);
void gadget_bridge_parser_debug(void);
#endif //GADGET_BRIDGE_H

View File

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@ -14,6 +15,7 @@
#include "wm_bt.h"
#include "ble_modem.h"
#include "ble_service.h"
#include "gadget_bridge.h"
extern int wm_printf(const char *fmt,...);
extern u32 tls_mem_get_avail_heapsize(void);
@ -97,10 +99,63 @@ static void tls_rtc_irq_cb(void *arg)
tls_rtc_timer_stop();
}
static void parser_event_cb(const gadget_bridge_event_data_t *gadget_bridge_event_data)
{
shell_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:
shell_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:
shell_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:
shell_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:
shell_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:
shell_printf("%d\n",gadget_bridge_event_data->find.find);
break;
case GADGET_BRIDGE_EVENT_TYPE_ACT:
shell_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;
default:
shell_printf("Unhandled\n");
}
}
static void nus_data_rx_cb(const uint8_t *data, uint16_t length)
{
//shell_printf("%s, received data : "NEW_LINE"#", __FUNCTION__);
//shell_putc('"');
for (uint16_t i = 0; i < length; i++)
{
if (data[i] < 32)
@ -108,6 +163,12 @@ static void nus_data_rx_cb(const uint8_t *data, uint16_t length)
else
shell_putc(data[i]);
}
//shell_printf("\","NEW_LINE);
shell_printf("# ");
gadget_bridge_parser_feed((const char *)data, length);
gadget_bridge_parser_code_e code;
while((code = gadget_bridge_parser_run()) == GADGET_BRIDGE_PARSER_CODE_PARSING);
shell_printf("Gadget bridge parser code : %s"NEW_LINE, gadget_bridge_parser_code_2_str(code));
//shell_puts("#"NEW_LINE);
}
@ -590,7 +651,10 @@ int _bluetooth(const shell_cmd_t *pcmd, int argc, char *const argv[])
shell_printf("Enabling bluetooth : %d with bt only : %d and service : %d"NEW_LINE, result, btOnly, service);
if(result)
{
gadget_bridge_parser_register_event_callback(&(parser_event_cb));
ble_service_register_nus_data_rx_cb(&(nus_data_rx_cb));
}
}
else if(strcmp(argv[1], "disable") == 0)
{
@ -618,46 +682,89 @@ int _bluetooth(const shell_cmd_t *pcmd, int argc, char *const argv[])
{
char cmd[200] = "";
bool found = false;
if(strcmp(argv[2], "toast") == 0)
bool to_return = false;
if(strcmp(argv[2], "toast") == 0 && argc == 5)
{
sprintf(cmd, "{\"t\":\"info\",\"msg\":\"%s\"} \n", argv[3]);
found = true;
gadget_bridge_toast_type_e toast_type = GADGET_BRIDGE_TOAST_TYPE_INFO;
if(strcmp(argv[3], "warn") == 0)
{
toast_type = GADGET_BRIDGE_TOAST_TYPE_WARN;
}
else if(strcmp(argv[3], "error") == 0)
{
toast_type = GADGET_BRIDGE_TOAST_TYPE_ERROR;
}
to_return = gadget_bridge_send_toast(toast_type, argv[4]);
}
else if(strcmp(argv[2], "bat") == 0)
if(strcmp(argv[2], "ver") == 0 && argc == 5)
{
to_return = gadget_bridge_send_firmware_version(argv[3], argv[4]);
}
else if(strcmp(argv[2], "bat") == 0 && argc == 6)
{
sprintf(cmd, "{\"t\":\"status\",\"bat\":%s,\"chg\":%s,\"volt\":%s} \n", argv[3], argv[4], argv[5]);
found = true;
uint8_t percent = atoi(argv[3]);
bool charging = atoi(argv[4]);
float volt = strtof(argv[5], NULL);
to_return = gadget_bridge_send_battery_status(percent, volt, charging);
}
else if(strcmp(argv[2], "find_phone") == 0)
else if(strcmp(argv[2], "find_phone") == 0 && argc == 4)
{
sprintf(cmd, "{\"t\":\"findPhone\",\"n\":%s} \n", argv[3]);
found = true;
to_return = gadget_bridge_send_find_phone(strcmp(argv[3], "true") == 0);
}
else if(strcmp(argv[2], "music") == 0)
else if(strcmp(argv[2], "music") == 0 && argc == 4)
{
sprintf(cmd, "{\"t\":\"music\",\"n\":\"%s\"} \n", argv[3]);
found = true;
gadget_bridge_music_control_e music_control = GADGET_BRIDGE_MUSIC_CONTROL_PAUSE;
if(strcmp(argv[3], "pause") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_PAUSE;
else if(strcmp(argv[3], "play") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_PLAY;
else if(strcmp(argv[3], "playpause") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_PLAYPAUSE;
else if(strcmp(argv[3], "next") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_NEXT;
else if(strcmp(argv[3], "previous") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_PREVIOUS;
else if(strcmp(argv[3], "volumeup") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_VOLUMEUP;
else if(strcmp(argv[3], "volumedown") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_VOLUMEDOWN;
else if(strcmp(argv[3], "forward") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_FORWARD;
else if(strcmp(argv[3], "rewind") == 0)
music_control = GADGET_BRIDGE_MUSIC_CONTROL_REWIND;
to_return = gadget_bridge_send_music_control(music_control);
}
else if(strcmp(argv[2], "notify") == 0)
{
sprintf(cmd, "{\"t\":\"notify\",\"n\":\"%s\",\"id\":%s,\"tel\":\"%s\",\"msg\":\"%s\"} \n", argv[3], argv[4], argv[5], argv[6]);
found = true;
}
else if(strcmp(argv[2], "act") == 0)
else if(strcmp(argv[2], "act") == 0 && argc == 5)
{
sprintf(cmd, "{\"t\":\"act\",\"hrm\":%s,\"stp\":%s} \n", argv[3], argv[4]);
found = true;
to_return = gadget_bridge_send_activity_data(atoi(argv[3]), atoi(argv[4]));
}
else
{
shell_printf("Unknown %s action, list of send_ble_notif actions :"NEW_LINE"toast info|warn|error \"msg\""NEW_LINE"bat \"XX%%\" 1|0 X.X"NEW_LINE"find_phone true|false"NEW_LINE"music play|pause|playpause|previous|next|volumeup|volumedown|forward|rewind"NEW_LINE"notify reply|dismiss_all id \"tel\" \"msg\""NEW_LINE
"act hrm steps"NEW_LINE, argv[2]);
}
shell_printf("Sending ble ntf : %d"NEW_LINE, to_return);
if(found)
{
shell_printf("Sending ble ntf with content : #%s# -> %s"NEW_LINE, cmd, ble_service_send_nus_data((const uint8_t *)cmd, strlen(cmd)) ? "success" : "failure");
}
else
/*else
{
shell_printf("Unknown %s action, list of send_ble_notif actions :"NEW_LINE"toast \"msg\""NEW_LINE"bat \"XX%%\" 1|0 X.X"NEW_LINE"find_phone true|false"NEW_LINE"music play|pause|previous|next"NEW_LINE"notify reply|dismiss_all id \"tel\" \"msg\""NEW_LINE
"act hrm steps"NEW_LINE, argv[2]);
}
}*/
}
else if(strcmp(argv[1], "up_conn_param") == 0)
{