System information

loop, but it’s a good example of how you might update or parse multiple rows in the
database.
§
The first part of our dialplan returns an ID number that we can use with the
ODBC_FETCH() function to iterate through the values returned. We’re going to assign this
ID to the LOGGED_IN_ID channel variable:
same => n,Set(LOGGED_IN_ID=${HOTDESK_LOGGED_IN_USER(${LOCATION})})
Here is the logout_login extension, which could potentially loop through multiple
rows:
exten => logout_login,1,NoOp()
; set all logged-in users on this device to logged-out status
same => n,Set(LOGGED_IN_ID=${HOTDESK_LOGGED_IN_USER(${LOCATION})})
same => n(start_loop),NoOp()
same => n,Set(WHO=${ODBC_FETCH(${LOGGED_IN_ID})})
same => n,GotoIf($["${ODBC_FETCH_STATUS}" = "FAILURE"]?cleanup)
same => n,Set(HOTDESK_STATUS(${WHO})=0) ; log out phone
same => n,Goto(start_loop)
same => n(cleanup),ODBCFinish(${LOGGED_IN_ID})
same => n,Goto(valid_login,set_login_status) ; return to logging in
We assign the first value returned from the database (e.g., the extension 1101) to the
WHO channel. Before doing anything, though, we check to see if the ODBC_FETCH() func-
tion was successful in returning data. If the ODBC_FETCH_STATUS channel variable con-
tains FAILURE, we have no data to work with, so we move to the cleanup priority label.
If we have data, we then pass the value of ${WHO} as an argument to the
HOTDESK_STATUS() function, which contains a value of 0. This is the first value passed
to HOTDESK_STATUS() and is shown as ${VAL1} in func_odbc.conf, where the function is
declared.
If you look at the HOTDESK_STATUS() function in func_odbc.conf you will see we could
also pass a second value, but we’re not doing that here since we want to remove any
values from that column in order to log out the user, which setting no value does
effectively.
After using HOTDESK_STATUS() to log out the user, we return to the start_loop priority
label to loop through all values, which simply executes a NoOp(). After attempting to
retrieve a value, we again check ODBC_FETCH_STATUS for FAILURE. If that value is found,
we move to the cleanup priority label, where we execute the ODBCFinish() dialplan
application to perform cleanup. We then return to the valid_login extension at the
set_login_status priority label.
The rest of the context should be fairly straightforward (if some of this doesn’t make
sense, we suggest you go back and refresh your memory with Chapters 6 and 10). The
one trick you may be unfamiliar with could be the usage of the ${ODBCROWS} channel
§ Also see “Multirow Functionality with func_odbc” on page 360 for more information and examples of parsing
multiple rows returned from the database.
Getting Funky with func_odbc: Hot-Desking | 365