@@ -60,6 +60,18 @@ const mp_obj_type_t mp_network_ppp_lwip_type;
60
60
61
61
static mp_obj_t network_ppp___del__ (mp_obj_t self_in );
62
62
63
+ static void network_ppp_stream_uart_irq_disable (network_ppp_obj_t * self ) {
64
+ if (self -> stream == mp_const_none ) {
65
+ return ;
66
+ }
67
+
68
+ // Disable UART IRQ.
69
+ mp_obj_t dest [3 ];
70
+ mp_load_method (self -> stream , MP_QSTR_irq , dest );
71
+ dest [2 ] = mp_const_none ;
72
+ mp_call_method_n_kw (1 , 0 , dest );
73
+ }
74
+
63
75
static void network_ppp_status_cb (ppp_pcb * pcb , int err_code , void * ctx ) {
64
76
network_ppp_obj_t * self = ctx ;
65
77
switch (err_code ) {
@@ -68,12 +80,9 @@ static void network_ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
68
80
break ;
69
81
case PPPERR_USER :
70
82
if (self -> state >= STATE_ERROR ) {
71
- // Disable UART IRQ.
72
- mp_obj_t dest [3 ];
73
- mp_load_method (self -> stream , MP_QSTR_irq , dest );
74
- dest [2 ] = mp_const_none ;
75
- mp_call_method_n_kw (1 , 0 , dest );
76
- // Indicate that the IRQ is disabled.
83
+ network_ppp_stream_uart_irq_disable (self );
84
+ // Indicate that we are no longer connected and thus
85
+ // only need to free the PPP PCB, not close it.
77
86
self -> state = STATE_ACTIVE ;
78
87
}
79
88
// Clean up the PPP PCB.
@@ -91,7 +100,9 @@ static mp_obj_t network_ppp_make_new(const mp_obj_type_t *type, size_t n_args, s
91
100
92
101
mp_obj_t stream = all_args [0 ];
93
102
94
- mp_get_stream_raise (stream , MP_STREAM_OP_READ | MP_STREAM_OP_WRITE );
103
+ if (stream != mp_const_none ) {
104
+ mp_get_stream_raise (stream , MP_STREAM_OP_READ | MP_STREAM_OP_WRITE );
105
+ }
95
106
96
107
network_ppp_obj_t * self = mp_obj_malloc_with_finaliser (network_ppp_obj_t , type );
97
108
self -> state = STATE_INACTIVE ;
@@ -105,7 +116,7 @@ static mp_obj_t network_ppp___del__(mp_obj_t self_in) {
105
116
network_ppp_obj_t * self = MP_OBJ_TO_PTR (self_in );
106
117
if (self -> state >= STATE_ACTIVE ) {
107
118
if (self -> state >= STATE_ERROR ) {
108
- // Still connected over the UART stream.
119
+ // Still connected over the stream.
109
120
// Force the connection to close, with nocarrier=1.
110
121
self -> state = STATE_INACTIVE ;
111
122
ppp_close (self -> pcb , 1 );
@@ -127,10 +138,11 @@ static mp_obj_t network_ppp_poll(size_t n_args, const mp_obj_t *args) {
127
138
}
128
139
129
140
mp_int_t total_len = 0 ;
130
- for (;;) {
141
+ mp_obj_t stream = self -> stream ;
142
+ while (stream != mp_const_none ) {
131
143
uint8_t buf [256 ];
132
144
int err ;
133
- mp_uint_t len = mp_stream_rw (self -> stream , buf , sizeof (buf ), & err , 0 );
145
+ mp_uint_t len = mp_stream_rw (stream , buf , sizeof (buf ), & err , 0 );
134
146
if (len == 0 ) {
135
147
break ;
136
148
}
@@ -149,6 +161,19 @@ static mp_obj_t network_ppp_poll(size_t n_args, const mp_obj_t *args) {
149
161
}
150
162
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (network_ppp_poll_obj , 1 , 2 , network_ppp_poll ) ;
151
163
164
+ static void network_ppp_stream_uart_irq_enable (network_ppp_obj_t * self ) {
165
+ if (self -> stream == mp_const_none ) {
166
+ return ;
167
+ }
168
+
169
+ // Enable UART IRQ to call PPP.poll() when incoming data is ready.
170
+ mp_obj_t dest [4 ];
171
+ mp_load_method (self -> stream , MP_QSTR_irq , dest );
172
+ dest [2 ] = mp_obj_new_bound_meth (MP_OBJ_FROM_PTR (& network_ppp_poll_obj ), MP_OBJ_FROM_PTR (self ));
173
+ dest [3 ] = mp_load_attr (self -> stream , MP_QSTR_IRQ_RXIDLE );
174
+ mp_call_method_n_kw (2 , 0 , dest );
175
+ }
176
+
152
177
static mp_obj_t network_ppp_config (size_t n_args , const mp_obj_t * args , mp_map_t * kwargs ) {
153
178
if (n_args != 1 && kwargs -> used != 0 ) {
154
179
mp_raise_TypeError (MP_ERROR_TEXT ("either pos or kw args are allowed" ));
@@ -160,8 +185,16 @@ static mp_obj_t network_ppp_config(size_t n_args, const mp_obj_t *args, mp_map_t
160
185
if (mp_map_slot_is_filled (kwargs , i )) {
161
186
switch (mp_obj_str_get_qstr (kwargs -> table [i ].key )) {
162
187
case MP_QSTR_stream : {
163
- mp_get_stream_raise (kwargs -> table [i ].value , MP_STREAM_OP_READ | MP_STREAM_OP_WRITE );
188
+ if (kwargs -> table [i ].value != mp_const_none ) {
189
+ mp_get_stream_raise (kwargs -> table [i ].value , MP_STREAM_OP_READ | MP_STREAM_OP_WRITE );
190
+ }
191
+ if (self -> state >= STATE_ACTIVE ) {
192
+ network_ppp_stream_uart_irq_disable (self );
193
+ }
164
194
self -> stream = kwargs -> table [i ].value ;
195
+ if (self -> state >= STATE_ACTIVE ) {
196
+ network_ppp_stream_uart_irq_enable (self );
197
+ }
165
198
break ;
166
199
}
167
200
default :
@@ -210,10 +243,14 @@ static u32_t network_ppp_output_callback(ppp_pcb *pcb, const void *data, u32_t l
210
243
}
211
244
mp_printf (& mp_plat_print , ")\n" );
212
245
#endif
246
+ mp_obj_t stream = self -> stream ;
247
+ if (stream == mp_const_none ) {
248
+ return 0 ;
249
+ }
213
250
int err ;
214
251
// The return value from this output callback is the number of bytes written out.
215
252
// If it's less than the requested number of bytes then lwIP will propagate out an error.
216
- return mp_stream_rw (self -> stream , (void * )data , len , & err , MP_STREAM_RW_WRITE );
253
+ return mp_stream_rw (stream , (void * )data , len , & err , MP_STREAM_RW_WRITE );
217
254
}
218
255
219
256
static mp_obj_t network_ppp_connect (size_t n_args , const mp_obj_t * args , mp_map_t * kw_args ) {
@@ -236,12 +273,7 @@ static mp_obj_t network_ppp_connect(size_t n_args, const mp_obj_t *args, mp_map_
236
273
}
237
274
self -> state = STATE_ACTIVE ;
238
275
239
- // Enable UART IRQ to call PPP.poll() when incoming data is ready.
240
- mp_obj_t dest [4 ];
241
- mp_load_method (self -> stream , MP_QSTR_irq , dest );
242
- dest [2 ] = mp_obj_new_bound_meth (MP_OBJ_FROM_PTR (& network_ppp_poll_obj ), MP_OBJ_FROM_PTR (self ));
243
- dest [3 ] = mp_load_attr (self -> stream , MP_QSTR_IRQ_RXIDLE );
244
- mp_call_method_n_kw (2 , 0 , dest );
276
+ network_ppp_stream_uart_irq_enable (self );
245
277
}
246
278
247
279
if (self -> state == STATE_CONNECTING || self -> state == STATE_CONNECTED ) {
0 commit comments