As for whether you can “save” the handles for later – that depends on whether you bond the connection with the other device (the GATT server). If you do, then yes you could save the handles as they’d be guaranteed not to change. However, we would probably just recommend that you look up the characteristic again on each connection. If you have know exactly which UUID you’re looking for, you can specify the service UUID on gattc_services(…) to filter the results, and then the characteristic UUID on gattc_characteristics(service_handle, …).
The other part of my question had to do with OTA transactions that must take place. getting the list of services seems to occur instantly. The services are part of the advertisement, but the characteristics for each service is not. So what I gather is that when I call gap_connection() the Xbee at that point does some scanning/reading which is why gattc_services() returns seemingly instantly … but what about when I enumerate the characteristics? There must be an OTA poll for those, when does that take place?