Skip to content

Commit f47c21f

Browse files
committed
pybricks.common.BLE: Fix broadcasting default to 0.
Broadcasting should only be possible when a channel is provided, just like observing defaults to no channels.
1 parent 4ff6e7b commit f47c21f

File tree

7 files changed

+25
-31
lines changed

7 files changed

+25
-31
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
- Relaxed speed limit from 1000 deg/s to 1200 deg/s for external Boost
1616
motor ([support#1623]).
17+
- Make `broadcast_channel` optional instead of defaulting to `0`.
1718

1819
### Fixed
1920
- Fixed persistent data not being deleted when swapping

pybricks/common/pb_type_ble.c

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static pbio_task_t broadcast_task;
5252

5353
typedef struct {
5454
mp_obj_base_t base;
55-
uint8_t broadcast_channel;
55+
mp_obj_t broadcast_channel;
5656
pbio_task_t *broadcast_task;
5757
observed_data_t observed_data[];
5858
} pb_obj_BLE_t;
@@ -263,14 +263,9 @@ static mp_obj_t pb_module_ble_broadcast(size_t n_args, const mp_obj_t *pos_args,
263263
// move hub is connected to Pybricks Code. Also, broadcasting interferes
264264
// with observing even when not connected to Pybricks Code.
265265

266-
// FIXME: This check is (and should only be) done in the BLE constructor,
267-
// but it may still pass there since 0 is a valid broadcast channel. That
268-
// should be fixed by defaulting to None if no broadcast channel is provided.
269-
#if PBSYS_CONFIG_BLUETOOTH_TOGGLE
270-
if (!pbsys_storage_settings_bluetooth_enabled()) {
271-
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Bluetooth not enabled"));
266+
if (self->broadcast_channel == mp_const_none) {
267+
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("no broadcast channel selected"));
272268
}
273-
#endif // PBSYS_CONFIG_BLUETOOTH_TOGGLE
274269

275270
// Stop broadcasting if data is None.
276271
if (data_in == mp_const_none) {
@@ -309,7 +304,7 @@ static mp_obj_t pb_module_ble_broadcast(size_t n_args, const mp_obj_t *pos_args,
309304
value.v.data[0] = index + 4; // length
310305
value.v.data[1] = MFG_SPECIFIC;
311306
pbio_set_uint16_le(&value.v.data[2], LEGO_CID);
312-
value.v.data[4] = self->broadcast_channel;
307+
value.v.data[4] = mp_obj_get_int(self->broadcast_channel);
313308

314309
pbdrv_bluetooth_start_broadcasting(self->broadcast_task, &value.v);
315310
return pb_module_tools_pbio_task_wait_or_await(self->broadcast_task);
@@ -516,7 +511,7 @@ static MP_DEFINE_CONST_OBJ_TYPE(pb_type_BLE,
516511
*
517512
* Do not call this function more than once unless pb_type_ble_start_cleanup() is called first.
518513
*
519-
* @param [in] broadcast_channel_in (int) The channel number to use for broadcasting.
514+
* @param [in] broadcast_channel_in (int) The channel number to use for broadcasting or None for no broadcasting.
520515
* @param [in] observe_channels_in (list[int]) A list of channels numbers to observe.
521516
* @returns A newly allocated object.
522517
* @throws ValueError If either parameter contains an out of range channel number.
@@ -525,29 +520,27 @@ mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channel
525520
// making the assumption that this is only called once before each pb_type_ble_start_cleanup()
526521
assert(observed_data == NULL);
527522

528-
mp_int_t broadcast_channel = mp_obj_get_int(broadcast_channel_in);
529-
530-
if (broadcast_channel < 0 || broadcast_channel > UINT8_MAX) {
531-
mp_raise_ValueError(MP_ERROR_TEXT("broadcast channel must be 0 to 255"));
523+
// Validate channel arguments.
524+
if (broadcast_channel_in != mp_const_none && (mp_obj_get_int(broadcast_channel_in) < 0 || mp_obj_get_int(broadcast_channel_in) > UINT8_MAX)) {
525+
mp_raise_ValueError(MP_ERROR_TEXT("Broadcast channel must be 0 to 255 or None"));
526+
}
527+
mp_int_t num_observe_channels = mp_obj_get_int(mp_obj_len(observe_channels_in));
528+
if (num_observe_channels < 0 || num_observe_channels > UINT8_MAX) {
529+
mp_raise_ValueError(MP_ERROR_TEXT("Too many observe channels"));
532530
}
533531

534-
mp_int_t num_channels = mp_obj_get_int(mp_obj_len(observe_channels_in));
535-
532+
// Raise if Bluetooth is attempted to be used while not enabled.
536533
#if PBSYS_CONFIG_BLUETOOTH_TOGGLE
537-
if (!pbsys_storage_settings_bluetooth_enabled() && (num_channels > 0 || broadcast_channel)) {
534+
if (!pbsys_storage_settings_bluetooth_enabled() && (num_observe_channels > 0 || broadcast_channel_in != mp_const_none)) {
538535
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Bluetooth not enabled"));
539536
}
540537
#endif // PBSYS_CONFIG_BLUETOOTH_TOGGLE
541538

542-
if (num_channels < 0 || num_channels > UINT8_MAX) {
543-
mp_raise_ValueError(MP_ERROR_TEXT("len observe channels must be 0 to 255"));
544-
}
545-
546-
pb_obj_BLE_t *self = mp_obj_malloc_var(pb_obj_BLE_t, observed_data_t, num_channels, &pb_type_BLE);
539+
pb_obj_BLE_t *self = mp_obj_malloc_var(pb_obj_BLE_t, observed_data_t, num_observe_channels, &pb_type_BLE);
547540
self->broadcast_task = &broadcast_task;
548-
self->broadcast_channel = broadcast_channel;
541+
self->broadcast_channel = broadcast_channel_in;
549542

550-
for (mp_int_t i = 0; i < num_channels; i++) {
543+
for (mp_int_t i = 0; i < num_observe_channels; i++) {
551544
mp_int_t channel = mp_obj_get_int(mp_obj_subscr(
552545
observe_channels_in, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL));
553546

@@ -564,10 +557,10 @@ mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channel
564557

565558
// globals for driver callback
566559
observed_data = self->observed_data;
567-
num_observed_data = num_channels;
560+
num_observed_data = num_observe_channels;
568561

569562
// Start observing.
570-
if (num_channels > 0) {
563+
if (num_observe_channels > 0) {
571564
pbio_task_t task;
572565
pbdrv_bluetooth_start_observing(&task, handle_observe_event);
573566
pb_module_tools_pbio_task_do_blocking(&task, -1);

pybricks/hubs/pb_type_cityhub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ typedef struct _hubs_CityHub_obj_t {
2828
static mp_obj_t hubs_CityHub_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
2929
#if PYBRICKS_PY_COMMON_BLE
3030
PB_PARSE_ARGS_CLASS(n_args, n_kw, args,
31-
PB_ARG_DEFAULT_INT(broadcast_channel, 0),
31+
PB_ARG_DEFAULT_NONE(broadcast_channel),
3232
PB_ARG_DEFAULT_OBJ(observe_channels, mp_const_empty_tuple_obj));
3333
#endif
3434

pybricks/hubs/pb_type_essentialhub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static mp_obj_t hubs_EssentialHub_make_new(const mp_obj_type_t *type, size_t n_a
4242
PB_ARG_DEFAULT_OBJ(top_side, pb_type_Axis_Z_obj),
4343
PB_ARG_DEFAULT_OBJ(front_side, pb_type_Axis_X_obj)
4444
#if PYBRICKS_PY_COMMON_BLE
45-
, PB_ARG_DEFAULT_INT(broadcast_channel, 0)
45+
, PB_ARG_DEFAULT_NONE(broadcast_channel)
4646
, PB_ARG_DEFAULT_OBJ(observe_channels, mp_const_empty_tuple_obj)
4747
#endif
4848
);

pybricks/hubs/pb_type_movehub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ static mp_obj_t hubs_MoveHub_make_new(const mp_obj_type_t *type, size_t n_args,
319319
PB_ARG_DEFAULT_INT(top_side, pb_type_Axis_Z_int_enum),
320320
PB_ARG_DEFAULT_INT(front_side, pb_type_Axis_X_int_enum)
321321
#if PYBRICKS_PY_COMMON_BLE
322-
, PB_ARG_DEFAULT_INT(broadcast_channel, 0)
322+
, PB_ARG_DEFAULT_NONE(broadcast_channel)
323323
, PB_ARG_DEFAULT_OBJ(observe_channels, mp_const_empty_tuple_obj)
324324
#endif
325325
);

pybricks/hubs/pb_type_primehub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static mp_obj_t hubs_PrimeHub_make_new(const mp_obj_type_t *type, size_t n_args,
6666
PB_ARG_DEFAULT_OBJ(top_side, pb_type_Axis_Z_obj),
6767
PB_ARG_DEFAULT_OBJ(front_side, pb_type_Axis_X_obj)
6868
#if PYBRICKS_PY_COMMON_BLE
69-
, PB_ARG_DEFAULT_INT(broadcast_channel, 0)
69+
, PB_ARG_DEFAULT_NONE(broadcast_channel)
7070
, PB_ARG_DEFAULT_OBJ(observe_channels, mp_const_empty_tuple_obj)
7171
#endif
7272
);

pybricks/hubs/pb_type_technichub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static mp_obj_t hubs_TechnicHub_make_new(const mp_obj_type_t *type, size_t n_arg
3232
PB_ARG_DEFAULT_OBJ(top_side, pb_type_Axis_Z_obj),
3333
PB_ARG_DEFAULT_OBJ(front_side, pb_type_Axis_X_obj)
3434
#if PYBRICKS_PY_COMMON_BLE
35-
, PB_ARG_DEFAULT_INT(broadcast_channel, 0)
35+
, PB_ARG_DEFAULT_NONE(broadcast_channel)
3636
, PB_ARG_DEFAULT_OBJ(observe_channels, mp_const_empty_tuple_obj)
3737
#endif
3838
);

0 commit comments

Comments
 (0)