@@ -60,6 +60,18 @@ const mp_obj_type_t mp_network_ppp_lwip_type;
6060
6161static mp_obj_t network_ppp___del__ (mp_obj_t self_in );
6262
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+
6375static void network_ppp_status_cb (ppp_pcb * pcb , int err_code , void * ctx ) {
6476 network_ppp_obj_t * self = ctx ;
6577 switch (err_code ) {
@@ -68,12 +80,9 @@ static void network_ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
6880 break ;
6981 case PPPERR_USER :
7082 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.
7786 self -> state = STATE_ACTIVE ;
7887 }
7988 // 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
91100
92101 mp_obj_t stream = all_args [0 ];
93102
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+ }
95106
96107 network_ppp_obj_t * self = mp_obj_malloc_with_finaliser (network_ppp_obj_t , type );
97108 self -> state = STATE_INACTIVE ;
@@ -105,7 +116,7 @@ static mp_obj_t network_ppp___del__(mp_obj_t self_in) {
105116 network_ppp_obj_t * self = MP_OBJ_TO_PTR (self_in );
106117 if (self -> state >= STATE_ACTIVE ) {
107118 if (self -> state >= STATE_ERROR ) {
108- // Still connected over the UART stream.
119+ // Still connected over the stream.
109120 // Force the connection to close, with nocarrier=1.
110121 self -> state = STATE_INACTIVE ;
111122 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) {
127138 }
128139
129140 mp_int_t total_len = 0 ;
130- for (;;) {
141+ mp_obj_t stream = self -> stream ;
142+ while (stream != mp_const_none ) {
131143 uint8_t buf [256 ];
132144 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 );
134146 if (len == 0 ) {
135147 break ;
136148 }
@@ -149,6 +161,19 @@ static mp_obj_t network_ppp_poll(size_t n_args, const mp_obj_t *args) {
149161}
150162static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (network_ppp_poll_obj , 1 , 2 , network_ppp_poll ) ;
151163
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+
152177static mp_obj_t network_ppp_config (size_t n_args , const mp_obj_t * args , mp_map_t * kwargs ) {
153178 if (n_args != 1 && kwargs -> used != 0 ) {
154179 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
160185 if (mp_map_slot_is_filled (kwargs , i )) {
161186 switch (mp_obj_str_get_qstr (kwargs -> table [i ].key )) {
162187 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+ }
164194 self -> stream = kwargs -> table [i ].value ;
195+ if (self -> state >= STATE_ACTIVE ) {
196+ network_ppp_stream_uart_irq_enable (self );
197+ }
165198 break ;
166199 }
167200 default :
@@ -210,10 +243,14 @@ static u32_t network_ppp_output_callback(ppp_pcb *pcb, const void *data, u32_t l
210243 }
211244 mp_printf (& mp_plat_print , ")\n" );
212245 #endif
246+ mp_obj_t stream = self -> stream ;
247+ if (stream == mp_const_none ) {
248+ return 0 ;
249+ }
213250 int err ;
214251 // The return value from this output callback is the number of bytes written out.
215252 // 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 );
217254}
218255
219256static 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_
236273 }
237274 self -> state = STATE_ACTIVE ;
238275
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 );
245277 }
246278
247279 if (self -> state == STATE_CONNECTING || self -> state == STATE_CONNECTED ) {
0 commit comments