Skip to content

Commit 0b1bc47

Browse files
committed
fixup! pbdrv/bluetooth: RFCOMM socket API.
Convert rfcomm_listen/connect into RFCOMMSocket. This object-oriented approach better matches what we do elsewhere in pybricks and the general pattern within Micropython overall.
1 parent 7134d3e commit 0b1bc47

File tree

1 file changed

+74
-49
lines changed

1 file changed

+74
-49
lines changed

pybricks/messaging/pb_module_messaging.c

Lines changed: 74 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -205,114 +205,139 @@ static void pb_type_messaging_rfcomm_socket_print(const mp_print_t *print, mp_ob
205205
mp_printf(print, "RFCOMMSocket(conn_id=%d)", self->conn.conn_id);
206206
}
207207

208-
static const mp_rom_map_elem_t pb_type_messaging_rfcomm_socket_locals_dict_table[] = {
209-
{MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj)},
210-
{MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj)},
211-
{MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj)},
212-
{MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj)},
213-
};
214-
static MP_DEFINE_CONST_DICT(pb_type_messaging_rfcomm_socket_locals_dict, pb_type_messaging_rfcomm_socket_locals_dict_table);
208+
// Forward declaration of the RFCOMMSocket type
209+
static const mp_obj_type_t pb_type_messaging_rfcomm_socket;
215210

216-
static MP_DEFINE_CONST_OBJ_TYPE(pb_type_messaging_rfcomm_socket, MP_QSTR_RFCOMMSocket, MP_TYPE_FLAG_NONE, print, pb_type_messaging_rfcomm_socket_print, protocol, &pb_type_messaging_rfcomm_socket_stream_p, locals_dict, &pb_type_messaging_rfcomm_socket_locals_dict);
217-
218-
static mp_obj_t pb_type_messaging_rfcomm_socket_new(const pbdrv_bluetooth_rfcomm_conn_t *conn) {
211+
// Constructor for RFCOMMSocket
212+
static mp_obj_t pb_type_messaging_rfcomm_socket_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
213+
mp_arg_check_num(n_args, n_kw, 0, 0, false);
219214
pb_type_messaging_rfcomm_socket_obj_t *self = mp_obj_malloc(pb_type_messaging_rfcomm_socket_obj_t, &pb_type_messaging_rfcomm_socket);
220-
self->conn = *conn;
215+
self->conn.conn_id = -1;
221216
return MP_OBJ_FROM_PTR(self);
222217
}
223218

224-
// RFCOMM connect
219+
// RFCOMM connect method
225220

226221
typedef struct {
222+
pb_type_messaging_rfcomm_socket_obj_t* socket;
227223
bdaddr_t bdaddr;
228224
int32_t timeout;
229-
pbdrv_bluetooth_rfcomm_conn_t conn;
230-
} pb_module_messaging_rfcomm_connect_context_t;
225+
} pb_type_messaging_rfcomm_socket_connect_context_t;
231226

232-
static pbio_error_t pb_module_messaging_rfcomm_connect_iterate(pbio_os_state_t *state, mp_obj_t parent_obj) {
233-
pb_module_messaging_rfcomm_connect_context_t *context = (pb_module_messaging_rfcomm_connect_context_t *)parent_obj;
234-
return pbdrv_bluetooth_rfcomm_connect(state, context->bdaddr, context->timeout, &context->conn);
227+
static pbio_error_t pb_type_messaging_rfcomm_socket_connect_iterate(pbio_os_state_t* state, mp_obj_t parent_obj) {
228+
pb_type_messaging_rfcomm_socket_connect_context_t* context = (pb_type_messaging_rfcomm_socket_connect_context_t*)parent_obj;
229+
return pbdrv_bluetooth_rfcomm_connect(state, context->bdaddr, context->timeout, &context->socket->conn);
235230
}
236231

237-
static mp_obj_t pb_module_messaging_rfcomm_connect_return_map(mp_obj_t context_obj) {
238-
pb_module_messaging_rfcomm_connect_context_t *context = (pb_module_messaging_rfcomm_connect_context_t *)context_obj;
239-
return pb_type_messaging_rfcomm_socket_new(&context->conn);
232+
static mp_obj_t pb_type_messaging_rfcomm_socket_connect_return_map(mp_obj_t context_obj) {
233+
pb_type_messaging_rfcomm_socket_connect_context_t* context = (pb_type_messaging_rfcomm_socket_connect_context_t*)context_obj;
234+
return MP_OBJ_FROM_PTR(context->socket);
240235
}
241236

242-
static mp_obj_t pb_module_messaging_rfcomm_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
243-
PB_PARSE_ARGS_FUNCTION(n_args, pos_args, kw_args,
244-
PB_ARG_REQUIRED(address),
245-
PB_ARG_DEFAULT_INT(timeout, 10000));
237+
static mp_obj_t pb_type_messaging_rfcomm_socket_connect(size_t n_args, const mp_obj_t* pos_args, mp_map_t* kw_args) {
238+
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args, pb_type_messaging_rfcomm_socket_obj_t, self, PB_ARG_REQUIRED(address), PB_ARG_DEFAULT_INT(timeout, 10000));
246239

247-
pb_module_messaging_rfcomm_connect_context_t *context = m_new(pb_module_messaging_rfcomm_connect_context_t, 1);
240+
// Check if socket is already connected
241+
if (pbdrv_bluetooth_rfcomm_is_connected(&self->conn)) {
242+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("socket is already connected"));
243+
}
244+
245+
pb_type_messaging_rfcomm_socket_connect_context_t* context = m_new(pb_type_messaging_rfcomm_socket_connect_context_t, 1);
246+
context->socket = self;
248247

249248
const char *address_str = mp_obj_str_get_str(address_in);
250249
if (!pbdrv_bluetooth_str_to_bdaddr(address_str, context->bdaddr)) {
251-
m_del(pb_module_messaging_rfcomm_connect_context_t, context, 1);
250+
m_del(pb_type_messaging_rfcomm_socket_connect_context_t, context, 1);
252251
mp_raise_ValueError(MP_ERROR_TEXT("invalid Bluetooth address format"));
253252
}
254253

255254
context->timeout = mp_obj_get_int(timeout_in);
256255
if (context->timeout < 0) {
257-
m_del(pb_module_messaging_rfcomm_connect_context_t, context, 1);
256+
m_del(pb_type_messaging_rfcomm_socket_connect_context_t, context, 1);
258257
mp_raise_ValueError(MP_ERROR_TEXT("timeout must be non-negative"));
259258
}
260259

261260
pb_type_async_t *awaitable_ptr = NULL;
262261
pb_type_async_t config = {
263-
.iter_once = pb_module_messaging_rfcomm_connect_iterate,
262+
.iter_once = pb_type_messaging_rfcomm_socket_connect_iterate,
264263
.parent_obj = MP_OBJ_FROM_PTR(context),
265-
.return_map = pb_module_messaging_rfcomm_connect_return_map,
264+
.return_map = pb_type_messaging_rfcomm_socket_connect_return_map,
266265
};
267266
return pb_type_async_wait_or_await(&config, &awaitable_ptr, true);
268267
}
269-
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_module_messaging_rfcomm_connect_obj, 1, pb_module_messaging_rfcomm_connect);
268+
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_type_messaging_rfcomm_socket_connect_obj, 1, pb_type_messaging_rfcomm_socket_connect);
270269

271-
// RFCOMM listen
270+
// RFCOMM listen method
272271

273272
typedef struct {
273+
pb_type_messaging_rfcomm_socket_obj_t* socket;
274274
int32_t timeout;
275-
pbdrv_bluetooth_rfcomm_conn_t conn;
276-
} pb_module_messaging_rfcomm_listen_context_t;
275+
} pb_type_messaging_rfcomm_socket_listen_context_t;
277276

278-
static pbio_error_t pb_module_messaging_rfcomm_listen_iterate(pbio_os_state_t *state, mp_obj_t parent_obj) {
279-
pb_module_messaging_rfcomm_listen_context_t *context = (pb_module_messaging_rfcomm_listen_context_t *)parent_obj;
280-
return pbdrv_bluetooth_rfcomm_listen(state, context->timeout, &context->conn);
277+
static pbio_error_t pb_type_messaging_rfcomm_socket_listen_iterate(pbio_os_state_t* state, mp_obj_t parent_obj) {
278+
pb_type_messaging_rfcomm_socket_listen_context_t* context = (pb_type_messaging_rfcomm_socket_listen_context_t*)parent_obj;
279+
return pbdrv_bluetooth_rfcomm_listen(state, context->timeout, &context->socket->conn);
281280
}
282281

283-
static mp_obj_t pb_module_messaging_rfcomm_listen_return_map(mp_obj_t context_obj) {
284-
pb_module_messaging_rfcomm_listen_context_t *context = (pb_module_messaging_rfcomm_listen_context_t *)context_obj;
285-
return pb_type_messaging_rfcomm_socket_new(&context->conn);
282+
static mp_obj_t pb_type_messaging_rfcomm_socket_listen_return_map(mp_obj_t context_obj) {
283+
pb_type_messaging_rfcomm_socket_listen_context_t* context = (pb_type_messaging_rfcomm_socket_listen_context_t*)context_obj;
284+
return MP_OBJ_FROM_PTR(context->socket);
286285
}
287286

288-
static mp_obj_t pb_module_messaging_rfcomm_listen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
289-
PB_PARSE_ARGS_FUNCTION(n_args, pos_args, kw_args,
290-
PB_ARG_DEFAULT_INT(timeout, 0));
287+
static mp_obj_t pb_type_messaging_rfcomm_socket_listen(size_t n_args, const mp_obj_t* pos_args, mp_map_t* kw_args) {
288+
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args, pb_type_messaging_rfcomm_socket_obj_t, self, PB_ARG_DEFAULT_INT(timeout, 0));
289+
290+
// Check if socket is already connected
291+
if (pbdrv_bluetooth_rfcomm_is_connected(&self->conn)) {
292+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("socket is already connected"));
293+
}
291294

292-
pb_module_messaging_rfcomm_listen_context_t *context = m_new(pb_module_messaging_rfcomm_listen_context_t, 1);
295+
pb_type_messaging_rfcomm_socket_listen_context_t* context = m_new(pb_type_messaging_rfcomm_socket_listen_context_t, 1);
296+
context->socket = self;
293297

294298
context->timeout = mp_obj_get_int(timeout_in);
295299
if (context->timeout < 0) {
296-
m_del(pb_module_messaging_rfcomm_listen_context_t, context, 1);
300+
m_del(pb_type_messaging_rfcomm_socket_listen_context_t, context, 1);
297301
mp_raise_ValueError(MP_ERROR_TEXT("timeout must be non-negative"));
298302
}
299303

300304
pb_type_async_t *awaitable_ptr = NULL;
301305
pb_type_async_t config = {
302-
.iter_once = pb_module_messaging_rfcomm_listen_iterate,
306+
.iter_once = pb_type_messaging_rfcomm_socket_listen_iterate,
303307
.parent_obj = MP_OBJ_FROM_PTR(context),
304-
.return_map = pb_module_messaging_rfcomm_listen_return_map,
308+
.return_map = pb_type_messaging_rfcomm_socket_listen_return_map,
305309
};
306310
return pb_type_async_wait_or_await(&config, &awaitable_ptr, true);
307311
}
308-
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_module_messaging_rfcomm_listen_obj, 0, pb_module_messaging_rfcomm_listen);
312+
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_type_messaging_rfcomm_socket_listen_obj, 0, pb_type_messaging_rfcomm_socket_listen);
313+
314+
static const mp_rom_map_elem_t pb_type_messaging_rfcomm_socket_locals_dict_table[] = {
315+
{MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&pb_type_messaging_rfcomm_socket_connect_obj)},
316+
{MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&pb_type_messaging_rfcomm_socket_listen_obj)},
317+
{MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj)},
318+
{MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj)},
319+
{MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj)},
320+
{MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj)},
321+
};
322+
static MP_DEFINE_CONST_DICT(pb_type_messaging_rfcomm_socket_locals_dict, pb_type_messaging_rfcomm_socket_locals_dict_table);
323+
324+
static MP_DEFINE_CONST_OBJ_TYPE(
325+
pb_type_messaging_rfcomm_socket,
326+
MP_QSTR_RFCOMMSocket,
327+
MP_TYPE_FLAG_NONE,
328+
make_new,
329+
pb_type_messaging_rfcomm_socket_make_new,
330+
print,
331+
pb_type_messaging_rfcomm_socket_print,
332+
protocol,
333+
&pb_type_messaging_rfcomm_socket_stream_p,
334+
locals_dict,
335+
&pb_type_messaging_rfcomm_socket_locals_dict);
309336

310337
static const mp_rom_map_elem_t messaging_globals_table[] = {
311338
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_messaging)},
312339
{MP_ROM_QSTR(MP_QSTR_local_address), MP_ROM_PTR(&pb_messaging_local_address_obj)},
313340
{MP_ROM_QSTR(MP_QSTR_bluetooth_scan), MP_ROM_PTR(&pb_messaging_bluetooth_scan_obj)},
314-
{MP_ROM_QSTR(MP_QSTR_rfcomm_connect), MP_ROM_PTR(&pb_module_messaging_rfcomm_connect_obj)},
315-
{MP_ROM_QSTR(MP_QSTR_rfcomm_listen), MP_ROM_PTR(&pb_module_messaging_rfcomm_listen_obj)},
316341
{MP_ROM_QSTR(MP_QSTR_RFCOMMSocket), MP_ROM_PTR(&pb_type_messaging_rfcomm_socket)},
317342
};
318343
static MP_DEFINE_CONST_DICT(pb_module_messaging_globals, messaging_globals_table);

0 commit comments

Comments
 (0)