Wln Tasks

Top  Previous  Next

True to the non-blocking operation philosophy of the entire system, the wln object does not stall the entire Tibbo BASIC/C application execution to wait for the Wi-Fi interface to complete required operation ("task"). You program gives the wln. object a task to perform, and then it is free to go and do other things.

There are nine wln. tasks:

Setting TX power (initiated by wln.settxpower method).  This is an "immediate" task.

Passively Scanning for Wi-Fi networks (initiated by wln.scan method).

Actively Scanning for Wi-Fi networks (initiated by wln.activescan method).

Setting WEP mode and key (initiated by wln.setwep method). This is an "immediate" task.

Setting WPA/WPA2 mode and key (initiated by wln.setwpa method).  This is an "immediate" task.

Associating with selected network (initiated wln.associate by method).

Creating own ad-hoc network (initiated by wln.networkstart method).

Disassociating from the network (initiated by wln.disassociate method).

Terminating own ad-hoc network (initiated by wln.networkstop method).

 

Three tasks on the list — wln.settxpower, wln.setwep, and wln.setwpa — are so-called immediate tasks. They complete as soon as they are started. If the execution advances to the next statement in the program then you know that these tasks are done with.

All remaining tasks take time to complete, and they complete asynchronously with respect to the program execution. The following example shows a wrong way of tasking:

 

 

'THIS WON'T WORK!

...

wln.scan("NET1")

wln.associate(wln.scanresultbssid,"NET1",wln.scanresultchannel,wln.scanresultbssmode) 'this task will be skipped over!

 

 

Here is how you should do this: use the wln.task read-only property and wait until the previous task is completed.

 

 

'A BETTER WAY

...

wln.scan("NET1")

while wln.task<>PL_WLN_TASK_IDLE 'waiting for the task to complete...

wend

...

wln.associate(wln.scanresultbssid,"NET1",wln.scanresultchannel,wln.scanresultbssmode)

while wln.task<>PL_WLN_TASK_IDLE 'waiting for the task to complete...

wend

...

 

 

The above approach still needs some refinement. Just making sure that the previous task has competed will not guarantee that your next task will be accepted. This is because some tasks can only be accepted under certain conditions. For example, you can't associate while you are already associated. Try this, and wln.associate will return 1- REJECTED.

 

 

'GOOD PROGRAMMING MEANS ANTICIPATING PROBLEMS

While wln.task<>PL_WLN_TASK_IDLE 'waiting for the previous task to complete...

Wend

...

If wln.associate(wln.scanresultbssid,"NET1",wln.scanresultchannel,wln.scanresultbssmode)<>ACCEPTED Then

  'We already made sure that the previous task was completed.

  'Hence, there is a more 'fundamental' reason for the rejection!

End If

 

 

Now, this is still not all. "Task completed" is not equal to "task completed successfully". In the above example, we were trying to associate with the "NET1" network. Now, have we actually succeeded? Find out by testing the value of wln.associationstate! For every task that may result in failure there is a way to know if the execution was successful or not.

 

 

'MORE CHECKING

While wln.task<>PL_WLN_TASK_IDLE 'waiting for the previous task to complete...

Wend

...

If wln.associate(wln.scanresultbssid,"NET1",wln.scanresultchannel,wln.scanresultbssmode)<>ACCEPTED Then

  'Handle this...

End If

While wln.task<>PL_WLN_TASK_IDLE 'waiting for association to complete...

Wend

'did we succeed?

If wln.associationstate<>PL_WLN_ASSOCIATED Then

  'something went wrong...

End If

...

 

 

One problem with the code in the above examples is that it is, essentially, blocking. Your application is not doing anything useful while the Wi-Fi interface is associating.

To take advantage of the event-driven nature of the system, you can base your execution flow 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

 

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

Sub On_sys_init

  ...

  wln.scan("CISCO1") 'start 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_SCAN:

    'wln.scan() completed

    If wln.scanresultssid="" Then

        'passive scan failed to reveal the network, let's try active scanning

        wln.activescan("CISCO1")

    Else

        'network discovered

        goto associate_now

    End If

 

  Case PL_WLN_TASK_ACTIVESCAN:

    'wln.activescan() completed

    If wln.scanresultssid="" Then

        'network still not found -- handle this

        ...

    End If

associate_now:    

     wln.associate(wln.scanresultbssid,"CISCO1",wln.scanresultchannel,wln.scanresultbssmode)

 

  Case PL_WLN_TASK_ASSOCIATE:

    'wln.associate() completed, proceed in this manner...

     ...

  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

 

 

Notice the on_wln_event in the code above. It allows us to catch "problems".