Sorry, guys, scratch my other bug report and the "fixes" suggested therein!!
It's not the service's "active" flag, it's the subscription's.
If the UpnpAcceptSubscription is not called, the subscription is not marked as "active", so no state variables will ever be sent.
I have a "lazy" architecture where a service may not be ready to publish any state data at the time of a subscription. Subscriptions are still accepted, there's just nothing to send, so UpnpAcceptSubscription is never called. As a result, the subscription is never marked as "active" via the genaInitNotify functions.
A best course of action would be to modify UpnpAcceptSubscription<...> functions so that they can accept *no* initial state information, but can still result in the subscription being marked as active. Technically, then, the "active" flag should be set here, not in the genaInitNotify<...> functions.
But the UpnpAccept functions don't muck with the subscription table, and it's more work than it's worth to move that code from the gena fucntions to the upnpapi functions.
So--- what I've done to correct this problem is to modify both UpnpAcceptSubscription<...> functions (in upnppapi.c) to accept an empty state list and still call the gena layer functions. The gena layer genaInitNotify<...> functions (gena_device.c) then mark the subscription as "active" *before* checking for an empty state set.
In genaInitNotify, a check for "var_count <= 0" is added immediately after the "subs->active = 1;" line. If this occurs, then all cleanup is performed and the function returns GENA_SUCCESS (since now, an empty state list is not an error). The same check is made for "PropSet == 0" in genaInitNotifyExt (just after the "subs->active = 1;" line).
I've modifified my proxy layer to call UpnpAcceptSubscriptionExt even when there is no state data to send. With the suggested changes to gena_device.c, later state changes are sent correctly.
This has solved my problem.