Wln Tasks

Top  Previous  Next

True to the non-blocking operation philosophy of the entire system, the wln object does not stall entire Tibbo Basic application execution to wait for the wln interface to complete required operation ("task"). There are five time-consuming tasks that the wln object performs. These are:

Setting TX power.
Scanning for Wi-Fi networks.
Setting WEP keys.
Associating with selected network.
Disassociating from the network.

 

Each of the above tasks has a corresponding method that initiates task execution but does not wait for the task to be completed. The methods are:

Settxpower
Scan
Setwep
Associate
Disassociate

 

The wln object can only work on a single task at a time. You cannot request another task execution until the previous one is finished! The following example shows a wrong way of tasking the wln object.

 

'THIS WON'T WORK!

...

wln.settxpower(255)

wln.scan("") 'this task will be skipped over!

 

Here is a better, but still flawed way. Each of the five methods returns a value that tells your application whether the task has been accepted for processing or rejected. You can request the task repeatedly, until it is finally accepted:

 

'NOT A VERY GOOD WAY TO WORK WITH WLN OBJECT!

(Also, many lines of code have been omitted For clarity)

...

While wln.settxpower(255)<>ACCEPTED 'attempt to execute wln.settxpower until it is accepted

Wend

...

While wln.associate<>ACCEPTED 'attempt to execute wln.associate until it is accepted

Wend

...

sock.connect 'premature!

 

 

In the above example, we first set the output power, then associate with the wireless network, then establish a socket connection over this network (many lines of code have been omitted for clarity!). The undesirable result of this code's execution will be that sock.connect will be called too early! When the wln.scan is accepted, the execution of your application will continue immediately, while the wln object will labor on the association process in the background. Therefore, by the time the sock.connect is reached, the association would not have been completed!

To avoid this, use the wln.task read-only property and wait until the task (of association) is completed:

 

'A BETTER WAY, BUT STILL NOT VERY GOOD

(Many lines of code have been omitted For clarity)

...

While wln.settxpower(255)<>ACCEPTED 'attempt to execute wln.settxpower until it is accepted

Wend

...

While wln.associate<>ACCEPTED 'attempt to execute wln.associate until it is accepted

Wend

While wln.task<>PL_WLN_TASK_IDLE 'very important...

Wend

...

sock.connect '... now this will happen at the right time

 

One problem with the above code is that your program may get stuck in the while-wend loop. For certain tasks, whether or not they are accepted depends on the current Wi-Fi state. For example, scanning (wln.scan) is not allowed while the Wi-Fi module is in the associated state (wln.associationstate= 1- PL_WLN_ASSOCIATED). So, you may get stuck in a loop while waiting for the wln.scan to be accepted. One way to avoid this is to make sure that the task is allowed before attempting to launch this task.

Something else is missing in the above code -- a check of the association result. One important thing to understand about the tasks is that their completion does not imply their success. For example, the association task will eventually be completed, even if the process itself fails. A separate property (wln.associationstate) must be interrogated in order to find out actual association result. So, one more check is needed:

 

'CORRECT CODE

'(Many lines of code have been omitted For clarity)

 

'make sure we can actually launch association attempt

If wln.associationstate=PL_WLN_Not_ASSOCIATED Then

  While wln.associate<>ACCEPTED 'attempt to execute wln.associate until it is accepted

  Wend

  While wln.task<>PL_WLN_TASK_IDLE 'very important...

  Wend

  If wln.associationstate=PL_WLN_ASSOCIATED Then 'this too...

     ...

     sock.connect '... now we definitely know we can proceed with out connection

  End If

End If

 

Association is not the only task that may routinely fail. Any task can be prevented from being accepted or completing successfully by the Wi-Fi module going offline. Wln.enabled read-only property indicates the status of the hardware. Also, the on_wln_event event is also generated when hardware disconnect is detected. Hardware problem, although improbable, is possible. Good code always checks everything:

 

'PARANOID CODE ENSURES DEVICE SURVIVAL

'(Many lines of code have been omitted For clarity)

...

wln.settxpower(255) 'task the Wi-Fi

While wln.task<>PL_WLN_TASK_IDLE 'wait for completion

Wend

If wln.enabled=NO Then

  'oh-ho... the Wi-Fi fell off the cliff

End If

...

'and so on in the same distrustful manner...

 

To take advantage of the event-driven nature of the system, you can also base your Wi-Fi control on the on_wln_task_complete event which is generated each time a task is completed. Completed_task argument of the event handler carries the code of the event that has been completed. Therefore, you can advance through steps in this manner:        

 

'THIS CODE TAKES FULL ADVANTAGE OF THE EVENT-DRIVEN NATURE OF THE SYSTEM

'(Many lines of code have been omitted for clarity)

 

'-------------------------------------------

Sub On_sys_init

  ...

  wln.settxpower(255) 'issue the task and don't wait

  ...

End Sub

 

'-------------------------------------------

Sub On_wln_task_complete(completed_task As pl_wln_tasks)

  Select Case completed task

  Case PL_WLN_TASK_SETTXPOWER:

     'here when wln.settxpower completes (we started it in the on_sys_init)

     wln.scan("") 'we now issue next task

 

  Case PL_WLN_TASK_SCAN:

     'here when wln.scan completes, and so on

     ...

  End Select

End Sub

 

'-------------------------------------------

Sub On_wln_event(wln_event As pl_wln_events)

  'here we catch hardware problems and disassociations -- also asynchronously 

End Sub