mirror of
https://github.com/google/pebble.git
synced 2025-06-07 18:53:11 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
147
src/fw/console/pulse_llc.c
Normal file
147
src/fw/console/pulse_llc.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "console/pulse_llc.h"
|
||||
#include "console/pulse_protocol_impl.h"
|
||||
|
||||
#include "console/pulse_internal.h"
|
||||
#include "util/attributes.h"
|
||||
#include "util/math.h"
|
||||
|
||||
#define LLC_INMSG_LINK_ESTABLISHMENT_REQUEST (1)
|
||||
#define LLC_INMSG_LINK_CLOSE_REQUEST (3)
|
||||
#define LLC_INMSG_ECHO_REQUEST (5)
|
||||
#define LLC_INMSG_CHANGE_BAUD (7)
|
||||
|
||||
#define LLC_OUTMSG_LINK_OPENED (2)
|
||||
#define LLC_OUTMSG_LINK_CLOSED (4)
|
||||
#define LLC_OUTMSG_ECHO_REPLY (6)
|
||||
#define LLC_OUTMSG_INVALID_LLC_MESSAGE (128)
|
||||
#define LLC_OUTMSG_UNKNOWN_PROTOCOL_NUMBER (129)
|
||||
|
||||
|
||||
static void prv_bad_packet_response(uint8_t type, uint8_t bad_id, void *body,
|
||||
size_t body_length);
|
||||
static void prv_handle_change_baud(void *body, size_t body_length);
|
||||
|
||||
|
||||
void pulse_llc_handler(void *packet, size_t length) {
|
||||
if (!length) {
|
||||
// Message too small; doesn't contain a type field.
|
||||
uint8_t *message = pulse_best_effort_send_begin(PULSE_PROTOCOL_LLC);
|
||||
*message = LLC_OUTMSG_INVALID_LLC_MESSAGE;
|
||||
pulse_best_effort_send(message, sizeof(uint8_t));
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t type = *(uint8_t*)packet;
|
||||
switch (type) {
|
||||
case LLC_INMSG_LINK_ESTABLISHMENT_REQUEST:
|
||||
pulse_llc_send_link_opened_msg();
|
||||
return;
|
||||
case LLC_INMSG_LINK_CLOSE_REQUEST:
|
||||
pulse_end();
|
||||
return;
|
||||
case LLC_INMSG_ECHO_REQUEST:
|
||||
*(uint8_t*)packet = LLC_OUTMSG_ECHO_REPLY;
|
||||
|
||||
uint8_t *message = pulse_best_effort_send_begin(PULSE_PROTOCOL_LLC);
|
||||
memcpy(message, packet, length);
|
||||
|
||||
pulse_best_effort_send(message, length);
|
||||
return;
|
||||
case LLC_INMSG_CHANGE_BAUD:
|
||||
prv_handle_change_baud((char*)packet + 1, length - 1);
|
||||
return;
|
||||
default:
|
||||
prv_bad_packet_response(LLC_OUTMSG_INVALID_LLC_MESSAGE, type,
|
||||
(char*)packet + 1, length - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void pulse_llc_link_state_handler(PulseLinkState link_state) {
|
||||
}
|
||||
|
||||
void pulse_llc_send_link_opened_msg(void) {
|
||||
typedef struct PACKED Response {
|
||||
uint8_t type;
|
||||
uint8_t pulse_version;
|
||||
uint16_t mtu;
|
||||
uint16_t mru;
|
||||
uint8_t timeout;
|
||||
} Response;
|
||||
|
||||
Response *response = pulse_best_effort_send_begin(PULSE_PROTOCOL_LLC);
|
||||
*response = (Response) {
|
||||
.type = LLC_OUTMSG_LINK_OPENED,
|
||||
.pulse_version = 1,
|
||||
.mtu = PULSE_MAX_SEND_SIZE + PULSE_MIN_FRAME_LENGTH,
|
||||
.mru = PULSE_MAX_RECEIVE_UNIT,
|
||||
.timeout = PULSE_KEEPALIVE_TIMEOUT_DECISECONDS
|
||||
};
|
||||
|
||||
pulse_best_effort_send(response, sizeof(Response));
|
||||
}
|
||||
|
||||
void pulse_llc_send_link_closed_msg(void) {
|
||||
uint8_t *link_close_response = pulse_best_effort_send_begin(
|
||||
PULSE_PROTOCOL_LLC);
|
||||
*link_close_response = LLC_OUTMSG_LINK_CLOSED;
|
||||
|
||||
pulse_best_effort_send(link_close_response, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
static void prv_bad_packet_response(uint8_t type, uint8_t bad_id, void *body,
|
||||
size_t body_length) {
|
||||
typedef struct PACKED Response {
|
||||
uint8_t type;
|
||||
uint8_t bad_identifier;
|
||||
char body[8];
|
||||
} Response;
|
||||
|
||||
Response *response = pulse_best_effort_send_begin(PULSE_PROTOCOL_LLC);
|
||||
*response = (Response) {
|
||||
.type = type,
|
||||
.bad_identifier = bad_id
|
||||
};
|
||||
|
||||
body_length = MIN(sizeof(response->body), body_length);
|
||||
if (body_length) {
|
||||
memcpy(response->body, body, body_length);
|
||||
}
|
||||
|
||||
pulse_best_effort_send(response, 2 + body_length);
|
||||
}
|
||||
|
||||
void pulse_llc_unknown_protocol_handler(uint8_t protocol, void *packet,
|
||||
size_t length) {
|
||||
prv_bad_packet_response(LLC_OUTMSG_UNKNOWN_PROTOCOL_NUMBER, protocol, packet,
|
||||
length);
|
||||
}
|
||||
|
||||
void prv_handle_change_baud(void *body, size_t body_length) {
|
||||
if (body_length != sizeof(uint32_t)) {
|
||||
// Don't send a response; the client will have already changed its receiver
|
||||
// baud rate.
|
||||
return;
|
||||
}
|
||||
uint32_t *new_baud = body;
|
||||
pulse_change_baud_rate(*new_baud);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue