562 Commits

Author SHA1 Message Date
Martin Preuss
a386ac43ab n32: 2nd iteration of enclosure. 2026-08-12 17:34:58 +02:00
Martin Preuss
2338f5333d reportsensors: report fancontrol state. 2026-08-12 00:07:32 +02:00
Martin Preuss
91880f1cfb added device. 2026-08-12 00:07:06 +02:00
Martin Preuss
1e6a3f06d0 avr: increment firmware version. 2026-08-11 23:48:04 +02:00
Martin Preuss
22e5e7853f reportSensors: increase interval to 3 mins. 2026-08-11 23:47:11 +02:00
Martin Preuss
3018b014bb avr/valsched: only repeat 0 values once. 2026-08-11 23:46:40 +02:00
Martin Preuss
1941b76aa7 avr: increment version. 2026-08-10 19:50:44 +02:00
Martin Preuss
c67fa6ebc9 n14, n25, n30: use new app LightControl instead of old app MA_Light 2026-08-10 19:50:29 +02:00
Martin Preuss
b9f2d9e59a avr: lengthen statistics report interval from 10mins to 30mins. 2026-08-10 19:49:39 +02:00
Martin Preuss
9d9ccbd46c n32:
- start ventilation slits lower (from 3 to 1.5mm) to also remove heat from
  under the pcb
- elevate notwork and power connectors by 2mm
2026-08-10 19:48:48 +02:00
Martin Preuss
568aec9c35 n32: started really working on enclosure. 2026-08-10 19:42:13 +02:00
Martin Preuss
7ad51a251b avr: new version of ds18b20 module.
works better with reportsensor app.
2026-08-07 23:48:15 +02:00
Martin Preuss
dd58bac1a3 avr: removed unneeded code. 2026-08-07 23:47:31 +02:00
Martin Preuss
69a5f40e60 avr: no longer handle REENUM messages (not used, anyway).
needed to get code size down for n30.
2026-08-07 23:46:30 +02:00
Martin Preuss
9c380316d2 avr: fixed a bug (was not setting CFLAG). 2026-08-07 23:45:43 +02:00
Martin Preuss
f973ce1b14 avr: more work on fan- and light controller app and modules. 2026-08-07 23:45:21 +02:00
Martin Preuss
296ead3241 avr: simplified modules. 2026-08-07 01:02:45 +02:00
Martin Preuss
f3820aee22 avr: fully implemented app light_control. 2026-08-07 00:43:42 +02:00
Martin Preuss
7bae2072aa avr: more code sharing. 2026-08-07 00:42:45 +02:00
Martin Preuss
44044e9bba tca: also rename FLAGBIT_UPDATED in TCA module. 2026-08-07 00:42:16 +02:00
Martin Preuss
928ebe1ec7 light_control: started working on new app (replaces ma_light). 2026-08-07 00:41:32 +02:00
Martin Preuss
db53d0d905 fan_control: fixed setting of default mode, moved FLAGBIT_UPDATED to TCA. 2026-08-07 00:39:40 +02:00
Martin Preuss
bbb6c4ac7d avr: start defining generic message with msgRef. 2026-08-06 18:48:05 +02:00
Martin Preuss
273c8d215a n32: remove old defines. 2026-08-06 18:47:21 +02:00
Martin Preuss
e7f9bea979 avr: move check for activated actor to htimCallActorOn 2026-08-06 18:47:03 +02:00
Martin Preuss
3155c499ed avr: enable guard source and 2nd trigger source. 2026-08-06 00:10:45 +02:00
Martin Preuss
1477293b49 avr: more comments, minor reformatting. 2026-08-06 00:09:59 +02:00
Martin Preuss
5bf067166e avr: fixed apidoc. 2026-08-06 00:09:21 +02:00
Martin Preuss
a2da503e7d avr: minor formatting. 2026-08-06 00:09:03 +02:00
Martin Preuss
fe1937c9cd e02, e06: added hardware category to device info 2026-08-06 00:08:37 +02:00
Martin Preuss
1cdec816f6 avr: fixed apidoc. 2026-08-06 00:08:09 +02:00
Martin Preuss
b961575906 avr: clarified api doc 2026-08-06 00:07:58 +02:00
Martin Preuss
27bb9d0f7f avr: fixed a typo. 2026-08-06 00:07:32 +02:00
Martin Preuss
80259d39c9 aqhome-tool: preset var. 2026-08-06 00:07:20 +02:00
Martin Preuss
3df7b69c2c aqhome-cgi: handle int values as well 2026-08-06 00:07:02 +02:00
Martin Preuss
e08054bbdf n32: use fan controller app 2026-08-06 00:06:31 +02:00
Martin Preuss
88a66f6822 avr: add complex fan controller app with base classes to be used by other apps as well.
- add modules
  - holdtimer (keep actor running while triggered)
  - triggeraction (connect actor with holdtimer)
- add app fan_controller
  - uses the modules mentioned above to turn on/off fans in connection
    with e.g. motion sensor nodes
2026-08-06 00:05:50 +02:00
Martin Preuss
d8498dceaf avr: add TextSel widget to CWidget. 2026-07-13 23:26:54 +02:00
Martin Preuss
3286d8e1d7 avr: fixed apidoc. 2026-07-13 23:25:12 +02:00
Martin Preuss
f5c530507e avr: more work on list widget. 2026-07-13 23:24:54 +02:00
Martin Preuss
56831ac53d more work on dialog class. 2026-07-13 23:24:32 +02:00
Martin Preuss
0675538258 lcd2: more work on light settings. 2026-07-13 23:23:49 +02:00
Martin Preuss
f81f031e23 Revert "avr: attempt to abstract IO code."
This reverts commit ae2a0f33b0.
2026-07-13 23:23:05 +02:00
Martin Preuss
ae2a0f33b0 avr: attempt to abstract IO code.
doesn't work with avra because of macro argument problems.
2026-07-13 23:22:47 +02:00
Martin Preuss
391c49d647 avr/co2_watch: change LED timing. 2026-07-13 23:21:51 +02:00
Martin Preuss
6a8f4156a5 add device e06. 2026-07-11 18:07:31 +02:00
Martin Preuss
29d18e8732 reportsensors: use table. 2026-07-11 18:06:57 +02:00
Martin Preuss
07db3879a1 n32: minor docu changes 2026-07-06 00:01:30 +02:00
Martin Preuss
f4c60cf428 n32: minor cleanup. 2026-07-05 23:52:07 +02:00
Martin Preuss
657853c1fe avr: minor reformatting. 2026-07-05 23:17:23 +02:00
Martin Preuss
276127e139 avr: removed NET_IFACE_OFFS_LASTPORTVALUE 2026-07-05 23:17:04 +02:00
Martin Preuss
a50c8da388 t03: fixed description. 2026-07-05 23:16:31 +02:00
Martin Preuss
e811cf1a8d n32: run at 8MHz now (1MHz is too slow for counting FAN tacho pulses). 2026-07-05 23:16:13 +02:00
Martin Preuss
bafb9c289a avr: fixed HW code for tn861. 2026-07-05 23:15:31 +02:00
Martin Preuss
a5559770ef avr: more work on MultiFAN module (now works, tested with a single fan). 2026-07-05 23:15:06 +02:00
Martin Preuss
9842d8a2e5 avr: more work on multifan module. 2026-07-05 20:27:28 +02:00
Martin Preuss
4dc2e0143f n32: enable Multifan module. 2026-07-05 20:21:13 +02:00
Martin Preuss
d51112e291 avr: enable module com2w2. 2026-07-05 20:08:02 +02:00
Martin Preuss
d4428128cb decreased flush limit, show received data (debug) 2026-07-05 20:07:34 +02:00
Martin Preuss
23cb3e62dc n32: use com2w2 instead of com2w 2026-07-05 20:07:05 +02:00
Martin Preuss
e6919677b3 n32: improved documentation. 2026-07-05 20:06:26 +02:00
Martin Preuss
db3f88f3af avr: added com2w2 (slightly improved version of com2w).
- move IRQ control to main code (only the main code knows exactly which
  combination of pins is used for com2)
- split one big module into multiple smaller files (easier to maintain)
2026-07-05 20:06:00 +02:00
Martin Preuss
b863e29612 com2w: removed unneeded code. 2026-07-05 20:03:29 +02:00
Martin Preuss
0ba4e879e6 more work on flush code. 2026-06-30 23:31:06 +02:00
Martin Preuss
f23806d884 propagate socket closure up to endpoint. 2026-06-30 23:30:48 +02:00
Martin Preuss
cdb9da2f9e n32: handle SETVALUE requests for fan speeds. 2026-06-29 22:17:29 +02:00
Martin Preuss
7a32f6deb7 avr/network: added field for last port value (should later be moved to com2w specific data). 2026-06-29 22:16:38 +02:00
Martin Preuss
cf2a0daae2 com2w: added routine COM2W_CheckPort
to be used by common pin change interrupt handler in n32
2026-06-29 22:15:58 +02:00
Martin Preuss
cbc3eab164 multiFan: handle SETVALUE messages. 2026-06-29 22:15:15 +02:00
Martin Preuss
183adb192e aqhome: added modality RPM 2026-06-29 22:14:16 +02:00
Martin Preuss
b784f6bb45 avr: added device n32 (FAN controller). 2026-06-29 17:48:02 +02:00
Martin Preuss
3ae542f61b com2w: use inr/outr macros for COM_IRQ_ADDR_CLK
the corresponding register is not inside the lower address space on some
devices (like ATtiny 861).
2026-06-29 17:45:42 +02:00
Martin Preuss
2974303007 avr: started working on MultiFAN module.
PWM basically works.
2026-06-29 17:44:22 +02:00
Martin Preuss
343562f6ca avr: added hw code for ATtiny 861. 2026-06-29 17:42:40 +02:00
Martin Preuss
fc2ef40d50 aqhome-nodes: read device from config file if not given as argument. 2026-06-08 11:23:49 +02:00
Martin Preuss
427d1e08f4 incremented version. 2026-06-01 19:12:18 +02:00
Martin Preuss
8488001f51 avr: removed old includes. 2026-06-01 19:11:52 +02:00
Martin Preuss
85b7b66db6 aqhome: simplified tty setup. 2026-06-01 19:11:15 +02:00
Martin Preuss
bda2a15da9 aqhome-cgi: fixed includes. 2026-06-01 19:10:50 +02:00
Martin Preuss
7ef6a22557 c03: added resources. 2026-06-01 15:58:36 +02:00
Martin Preuss
54ebc5ec69 add device e5. 2026-06-01 15:58:06 +02:00
Martin Preuss
b5c9557671 ipc2: improved flush code in tty object.
we still occasionally see problems with partially flushed serial port
especially when using /dev/ttyACM0.
2026-06-01 15:57:43 +02:00
Martin Preuss
6117ce5cad nodes: improved handling of memstat messages. 2026-06-01 15:56:38 +02:00
Martin Preuss
c262c4a56a aqhome-cgi: use service code from AqCGI. 2026-06-01 15:55:42 +02:00
Martin Preuss
62741e1c16 incremented version. 2026-06-01 15:54:47 +02:00
Martin Preuss
f5ae108756 aqhome-cgi: removed unneeded lines. 2026-05-29 17:22:33 +02:00
Martin Preuss
b8d2fc76eb aqhome-cgi: use AQH_ModService_DenyRequest
this function redirects to the login page and then to the requested page.
2026-05-29 17:22:12 +02:00
Martin Preuss
03db148a3b aqhome-cgi: added some functions for redirection headers. allow vars in static files. 2026-05-29 17:21:11 +02:00
Martin Preuss
5bb50d4187 aqhome-cgi: choose graph params according to modality. 2026-05-29 17:19:19 +02:00
Martin Preuss
62c86285f5 aqhome-cgi: removed unused line. 2026-05-29 17:18:50 +02:00
Martin Preuss
78ea72efe0 aqhome-cgi: add login url. 2026-05-29 17:18:20 +02:00
Martin Preuss
a65e6fbec2 textsel: use index instead of ressource id as value for the widget. 2026-05-23 11:06:39 +02:00
Martin Preuss
776ec7a363 gui: minor reformatting. 2026-05-23 11:06:12 +02:00
Martin Preuss
323122c4c7 c03: use far call 2026-05-23 01:43:34 +02:00
Martin Preuss
a3220d74b1 avr: added List_GetItemAt 2026-05-23 01:43:18 +02:00
Martin Preuss
710162e242 gui: sorted files. started working on TextSel class. 2026-05-23 01:43:04 +02:00
Martin Preuss
4b13f16e05 gui: improved Label class (can now have a suffix to reduce FLASH usage).
- e.g. light1 and light2 can now share the string but have different suffix
- allow for initially empty text
2026-05-23 01:41:58 +02:00
Martin Preuss
15edfd46e4 c03: fixed apidoc. 2026-05-18 17:15:09 +02:00
Martin Preuss
0c42acf76d gui: added image label (image plus text). 2026-05-18 17:14:50 +02:00
Martin Preuss
311741ae64 gui: added Widget_GetRessource 2026-05-18 17:14:17 +02:00
Martin Preuss
4ad55e2c6e gui: minor reformatting. 2026-05-18 17:13:31 +02:00
Martin Preuss
18e1751e14 gui: added missing register setting. 2026-05-18 17:13:03 +02:00
Martin Preuss
b2e5be974e gui: added LONG mode for buttons (handles short and long presses). 2026-05-18 17:12:39 +02:00
Martin Preuss
ed899dbe6f gui: re-enable NetStats window. 2026-05-14 13:45:39 +02:00
Martin Preuss
401cfc9ffb gui: rewrote NetStatWin to use CDIALOG (much more code sharing). 2026-05-14 13:45:13 +02:00
Martin Preuss
0c4a2aace9 gui: use CDialog_GetChildValue 2026-05-14 13:44:25 +02:00
Martin Preuss
73b7699054 avr: add CDialog_GetChildValue/CDialog_SetChildValue (more code sharing). 2026-05-14 13:44:10 +02:00
Martin Preuss
79e7ac47d9 c03: use DIALOG as base class for MenuWin 2026-05-13 20:08:36 +02:00
Martin Preuss
76def6c8dc gui: set WIDGET_FLAGS_VISIBLE_BIT early in Dialog_OnShow 2026-05-13 20:07:45 +02:00
Martin Preuss
a4722bc8f6 gui: fixed a typo. 2026-05-13 20:07:12 +02:00
Martin Preuss
32061554c0 c03: enable climate window. 2026-05-13 00:31:13 +02:00
Martin Preuss
3d14c54df3 gui: adjusted climate window and SensorWatch to latest changes. 2026-05-13 00:30:58 +02:00
Martin Preuss
1b0d36b84d avr: fixed apidoc. 2026-05-13 00:30:26 +02:00
Martin Preuss
313b2c05a1 gui: implemented DlgLightConns_OnCmdLight and DlgLightConns_OnDlgEndLight. 2026-05-11 12:11:33 +02:00
Martin Preuss
d54a259060 gui: adapted ScreenSaver to latest changes. 2026-05-11 11:55:56 +02:00
Martin Preuss
d07f411e51 gui: implement DlgLightConns_OnCmdMotion2 and DlgLightConns_OnDlgEndMotion2 2026-05-11 11:55:16 +02:00
Martin Preuss
b4ac70dbd1 gui: removed unneeded code, use CDialog_DefaultSignalmap as fallback signal map 2026-05-11 11:54:23 +02:00
Martin Preuss
d34062df39 gui: make CDialog a full object with signal map, implement "OnMkContent". 2026-05-11 11:53:37 +02:00
Martin Preuss
b927bfdab6 gui: added dialog signals DIALOG_SIGNAL_MKCONTENT and DIALOG_SIGNAL_RMCONTENT. 2026-05-11 11:52:23 +02:00
Martin Preuss
39b3d4d174 gui: adapt to latest changes.
need to work on other MainWindow derivates next.
2026-05-11 00:42:42 +02:00
Martin Preuss
0ec290e29c gui: allow setting OPTS from r16.
this is used by the caller to specify whether standard dialog buttons are
to be added.
2026-05-11 00:42:05 +02:00
Martin Preuss
fc28a57b05 gui: define signals for dialog class, create to-be-shared code. 2026-05-11 00:41:16 +02:00
Martin Preuss
cd0d74d491 MainWindow: no longer auto-create content widget
will be called later by deriving classes upon SHOW signal to save on
SDRAM.
2026-05-11 00:40:28 +02:00
Martin Preuss
800b6d316e widget: save Z 2026-05-11 00:39:19 +02:00
Martin Preuss
556cbb1d48 c03: temporarily disable c03AppCreateWinClimate 2026-05-10 17:03:34 +02:00
Martin Preuss
85a837d9ef avr: re-enable heapCoalecseUp 2026-05-10 17:03:13 +02:00
Martin Preuss
6787b4f527 avr: use Heap_AllocAndZero 2026-05-10 17:02:53 +02:00
Martin Preuss
455b81d8eb avr: minor formatting. 2026-05-10 17:02:41 +02:00
Martin Preuss
41c947a486 DEBUG: temporarily disable heapCoalecseUp. 2026-05-09 02:03:31 +02:00
Martin Preuss
afc6d3de24 debug: increase frequency of memstats again (now every minute). 2026-05-09 02:03:11 +02:00
Martin Preuss
8e6017a4ad c03: allocate settings. 2026-05-09 02:02:35 +02:00
Martin Preuss
2dec641f04 gui: added comment. 2026-05-09 02:02:08 +02:00
Martin Preuss
184195ba9f gui: fixed apidoc. 2026-05-09 02:01:55 +02:00
Martin Preuss
bb753b6009 gui: comment-out code 2026-05-09 02:01:39 +02:00
Martin Preuss
d55c9b0cb7 gui: fixed some problems. 2026-05-09 02:01:11 +02:00
Martin Preuss
dad807e7ad gui: add routine to destroy objects outside event loop. 2026-05-09 02:00:41 +02:00
Martin Preuss
c165432c1c gui: fixed a bug (missing ret). 2026-05-09 02:00:06 +02:00
Martin Preuss
21b6a992ff gui: fixed ValueLabel to also use WIDGET_VALUE_CURRENTVALUE 2026-05-09 01:59:47 +02:00
Martin Preuss
35a45e5cb2 gui: fixed some bugs.
calling a dialog from another basically works now.
2026-05-09 01:58:38 +02:00
Martin Preuss
941948fc11 Revert "gui, heap: modified how the heap works."
This reverts commit abe0bef99a.
2026-05-08 22:08:58 +02:00
Martin Preuss
abe0bef99a gui, heap: modified how the heap works.
not well enough tested, yet.
2026-05-08 22:08:47 +02:00
Martin Preuss
22b3b14dfb gui: started working on connections page for light settings. 2026-05-08 22:08:06 +02:00
Martin Preuss
f00b7975c0 gui: added ressources. 2026-05-08 22:07:07 +02:00
Martin Preuss
97fd75e3ba c03: fixed calculation of heap size. decrease number of buffers. 2026-05-08 22:06:55 +02:00
Martin Preuss
33c750bb34 minor reformatting. 2026-05-08 22:06:13 +02:00
Martin Preuss
8a4b63422a avr: temporarily increased frequency of memstat messages. 2026-05-08 22:05:53 +02:00
Martin Preuss
781478d2d2 gui: emit signal when dialog button clicked. 2026-05-08 12:31:53 +02:00
Martin Preuss
db97cf9644 gui: removed unused code. 2026-05-08 12:21:55 +02:00
Martin Preuss
d149c5667f gui: more work on dialogs. 2026-05-08 12:20:43 +02:00
Martin Preuss
b0d9c46d87 gui: allow for style setting in parent of configured widgets. 2026-05-08 10:15:46 +02:00
Martin Preuss
d236c9571e c03: fixed overwrite detection. 2026-05-08 10:15:04 +02:00
Martin Preuss
67e084b856 gui: introduced base class for dialogs. 2026-05-08 10:04:25 +02:00
Martin Preuss
c746abcc0f gui: added value WIDGET_VALUE_STYLE 2026-05-08 10:03:51 +02:00
Martin Preuss
c4af86c4f2 c03: added ressources. 2026-05-08 10:03:05 +02:00
Martin Preuss
f154146b14 gui: improved style handling. 2026-05-08 10:02:34 +02:00
Martin Preuss
cc65fb8f0b c03: debug dialog: DlgNodeValueId. 2026-05-08 00:31:49 +02:00
Martin Preuss
245181112a gui: started with dialog NodeValueId
- lets you input a node address and a value id
- needed e.g. for light settings
2026-05-08 00:31:31 +02:00
Martin Preuss
5513878b24 gui: removed CWidget_GetChildBySelector (use OBJ_GetChildBySelector). 2026-05-08 00:30:10 +02:00
Martin Preuss
31dca13123 gui: fixed HSpinner (wasn't propagating values to ValueLabel). 2026-05-08 00:29:26 +02:00
Martin Preuss
d713e774ee gui: added Widget_GetCurrentValue, Widget_GetMinValue, Widget_GetMaxValue 2026-05-08 00:29:00 +02:00
Martin Preuss
c48423b4c1 gui: added OBJ_GetChildBySelector 2026-05-08 00:28:31 +02:00
Martin Preuss
6cb0ecd9ba gui: added some text ressources. 2026-05-08 00:28:07 +02:00
Martin Preuss
80ac3cbebd gui: added DESTROY flag. 2026-05-07 22:10:45 +02:00
Martin Preuss
8c077d2931 gui: more documentation. 2026-05-07 22:10:16 +02:00
Martin Preuss
12a701014a gui: use CWidget. 2026-05-07 22:09:55 +02:00
Martin Preuss
d1c823c11e gui: more generic approach to generating widgets from config. 2026-05-07 22:09:25 +02:00
Martin Preuss
5300e50440 gui: add routine CDialog_CreateWidgets (to be used outside CDIALOG). 2026-05-06 23:57:57 +02:00
Martin Preuss
1c90e66f74 c03: use new CDIALOG class for LightSettings dialog. 2026-05-06 23:44:46 +02:00
Martin Preuss
dfeedecf22 gui: move some value definitions to WIDGET class (need to do the same for VALUE_LABEL!) 2026-05-06 23:44:04 +02:00
Martin Preuss
ce1fd901e7 gui: added configuration-based dialog
creates a dialog with widgets from a configuration stored as sequence of
bytes in flash.
2026-05-06 23:43:15 +02:00
Martin Preuss
5483df48cd c03: test light settings dialog. 2026-05-06 17:17:51 +02:00
Martin Preuss
c7f2206228 c03: added missing include. 2026-05-06 17:17:35 +02:00
Martin Preuss
d50ff7f74f c03: add line to light settings dialog. 2026-05-06 17:17:13 +02:00
Martin Preuss
10496a67ef gui: use TextButtons for HSpinner. 2026-05-06 17:16:50 +02:00
Martin Preuss
44a8acb845 c03: added ressources. 2026-05-06 17:16:17 +02:00
Martin Preuss
538bb48968 gui: added documentation 2026-05-06 17:15:48 +02:00
Martin Preuss
c7de06f812 gui: added textButton 2026-05-06 17:15:28 +02:00
Martin Preuss
957c2ccc71 avr: test keypads. 2026-05-06 00:26:20 +02:00
Martin Preuss
4d57f15dad gui: started working on keypads. 2026-05-06 00:26:08 +02:00
Martin Preuss
0771986b28 e02: no longer autoreset MCP2221. 2026-05-06 00:25:45 +02:00
Martin Preuss
bcbd777b8f ttyObject: still problems recovering from desynced connection.
tcflush doesn't seem to completely flush the os buffers...
2026-05-06 00:25:23 +02:00
Martin Preuss
636d6ce643 gui: fixed a bug. 2026-05-05 21:15:29 +02:00
Martin Preuss
8a41b156aa gui: added routines
- Widget_DrawRect
- Widget_DrawCharAt
- Widget_GetNormalColors
- Widget_GetActivatedColors
2026-05-05 21:15:03 +02:00
Martin Preuss
c059b6aad3 avr: add 8 bit multiplication. 2026-05-05 17:25:50 +02:00
Martin Preuss
43c69ca22e avr: incremented firmware version. 2026-05-04 22:51:33 +02:00
Martin Preuss
f98e591ca8 avr: improved apidoc. 2026-05-04 22:51:20 +02:00
Martin Preuss
596def6e10 avr: added missing build files. 2026-05-04 21:50:26 +02:00
Martin Preuss
3c89a35645 e05: use 23LC512 (RAM) and 25LC256 (EEPROM) via spi_sw. 2026-05-04 21:45:50 +02:00
Martin Preuss
99aae535e7 avr: added modules spi_sw, 23LC512, 25LC256 2026-05-04 21:44:55 +02:00
Martin Preuss
6bc747938b e02: fixed a typo. 2026-05-04 15:01:26 +02:00
Martin Preuss
2e6c846f1e avr: removed more occurrences of MODULES_LED_ACTIVITY 2026-05-04 14:47:35 +02:00
Martin Preuss
d14845db7a t03: adapted to earlier changes. 2026-05-04 14:43:11 +02:00
Martin Preuss
adcca2f306 avr: removed old definitions. 2026-05-04 14:42:48 +02:00
Martin Preuss
44bb477680 avr: fixed definitions to use updated LED module. 2026-05-04 14:35:55 +02:00
Martin Preuss
67d5d1687d avr: updated apps and modules to latest changes. 2026-05-04 14:35:20 +02:00
Martin Preuss
bea424de36 sgp30: fixed apidoc. 2026-05-04 13:59:04 +02:00
Martin Preuss
a9147f911c avr: removed LED, renamed LED_SIMPLE to LED, introduces LED1, LED2, LED3 2026-05-04 13:58:39 +02:00
Martin Preuss
a9a87ab94b avr: added app CO2WATCH 2026-05-04 13:57:09 +02:00
Martin Preuss
10fcb053a0 sk6812: store current state (not used for now). 2026-05-04 10:26:14 +02:00
Martin Preuss
9613157753 added flash instructions for n31. 2026-05-04 10:25:46 +02:00
Martin Preuss
7f28c22f6a improved error handling on msg desync on TTY connections.
just directly flush on error and return to normal operations immediately.
2026-05-04 10:25:29 +02:00
Martin Preuss
47cd79d7aa added debug msg. 2026-05-04 10:24:26 +02:00
Martin Preuss
7543afa7b8 c03: create light settings window. 2026-04-30 00:11:46 +02:00
Martin Preuss
721b06a044 gui: more work on light settings window. 2026-04-30 00:11:19 +02:00
Martin Preuss
db4825f483 gui: fixed lightsettings. 2026-04-30 00:10:56 +02:00
Martin Preuss
5856913b6c gui: use given button mode. 2026-04-30 00:10:30 +02:00
Martin Preuss
8b25922b88 gui: more work on spinner. 2026-04-30 00:10:07 +02:00
Martin Preuss
5767329895 gui: fixed CFLAG return value. 2026-04-30 00:08:22 +02:00
Martin Preuss
7173ea14ac gui: add OBJECT_OPTS_TIMER_BIT to buttons, decrease repeat time. 2026-04-30 00:07:28 +02:00
Martin Preuss
ac832bfefc avr: added ressources. 2026-04-30 00:06:32 +02:00
Martin Preuss
8bd1ceaec2 avr: fixed a bug. 2026-04-28 00:23:48 +02:00
Martin Preuss
6cf572ab44 avr: started woring on hspinner. 2026-04-27 23:31:26 +02:00
Martin Preuss
1a31985c58 avr: minor changes to lightsettings. 2026-04-27 23:31:12 +02:00
Martin Preuss
8b17a63fa1 avr: more work on c03 and gui. 2026-04-27 23:30:49 +02:00
Martin Preuss
3b7317bb0f avr: added EepromTlv_FindNext 2026-04-27 19:16:26 +02:00
Martin Preuss
606404095e avr: add e04 device. 2026-04-27 16:05:32 +02:00
Martin Preuss
f656895198 c03: add boot loader entry to README. 2026-04-27 16:05:19 +02:00
Martin Preuss
c49e794827 minor formatting. 2026-04-27 16:04:53 +02:00
Martin Preuss
59c05d379c aqhome: add and implement a flush function for fd/tty objects. 2026-04-27 16:04:42 +02:00
Martin Preuss
0ac20ba82c aqhome-nodes: send heartbeat message to interface every 2mins.
e02 now expects this message. If for at least 10mins no such msg is
received the USB interface is reset.
2026-04-27 16:01:12 +02:00
Martin Preuss
a0360d5373 avr: re-enable APPS_STATS in n25. 2026-04-27 00:41:07 +02:00
Martin Preuss
9b10e454a9 avr: fixed apidoc. 2026-04-27 00:40:39 +02:00
Martin Preuss
a31f360e3c avr: cleanup e03. 2026-04-27 00:40:26 +02:00
Martin Preuss
5e7c01c100 avr: added e04 and e05. 2026-04-27 00:40:00 +02:00
Martin Preuss
accc7d41a2 avr: added module ds1307. 2026-04-27 00:39:02 +02:00
Martin Preuss
14edff1369 avr: save X in Main_HandleValueMsg 2026-04-27 00:37:30 +02:00
Martin Preuss
6948028284 avr: optimized app MA_LIGHT (from 3295 to 3222 words). 2026-04-26 15:18:38 +02:00
Martin Preuss
c6fdc94a46 avr: minor changes. 2026-04-26 12:48:25 +02:00
Martin Preuss
74e471ef28 avr: guard with precompiler directives. 2026-04-26 12:47:50 +02:00
Martin Preuss
240624c727 avr: added README. 2026-04-26 12:47:14 +02:00
Martin Preuss
abac650427 avr: removed old modules. 2026-04-26 12:47:01 +02:00
Martin Preuss
cacfdaa6e7 n30: removed unneeded code, re-enable stats app. 2026-04-26 12:46:08 +02:00
Martin Preuss
0db8eda08b avr: more work on README. 2026-04-25 20:10:22 +02:00
Martin Preuss
d48745394c avr: add room field. 2026-04-25 20:01:51 +02:00
Martin Preuss
bed8a4afc2 more documentation. 2026-04-25 20:01:26 +02:00
Martin Preuss
93aa9b46c3 avr: more work on gui. 2026-04-21 00:01:15 +02:00
Martin Preuss
8c567c3a87 avr: adapted to latest changes. 2026-04-21 00:00:51 +02:00
Martin Preuss
00bb83ef4e avr: use Heap_AllocAndZero, added OBJ_EmitSignalWithSelector 2026-04-21 00:00:14 +02:00
Martin Preuss
0eeff3634c avr: added Heap_AllocAndZero 2026-04-20 23:59:46 +02:00
Martin Preuss
ea286e68ce avr: minor reformatting. 2026-04-20 23:59:33 +02:00
Martin Preuss
decd2120a4 avr: fixed more typos. 2026-04-20 23:59:16 +02:00
Martin Preuss
49c0088b0d n29: removed unneeded files. 2026-04-20 23:58:31 +02:00
Martin Preuss
71a9df7332 avr: fixed typos 2026-04-20 23:57:41 +02:00
Martin Preuss
abe218e7b0 avr: reorganized common code. 2026-04-20 23:56:52 +02:00
Martin Preuss
2d2105ae00 n30: removed unused value. 2026-04-18 16:17:27 +02:00
Martin Preuss
a995313750 n21, n28: use LED_SIMPLE instead of LED_ACTIVITY.
LED_SIMPLE can now also show activity.
2026-04-18 16:17:07 +02:00
Martin Preuss
23a8439b73 c03: remove unused values. 2026-04-18 16:16:06 +02:00
Martin Preuss
cc3c9dbd57 aqhome-cgi: fixed ids of created roles (now start with 1). 2026-04-18 16:15:42 +02:00
Martin Preuss
e5f9be1bff n29: no longer support sgp30 (is now supported by n31). 2026-04-16 23:45:22 +02:00
Martin Preuss
77484433f7 n29: removed LEDTIMING, SGP30_TVOC and SGP30_CO2 2026-04-16 23:44:57 +02:00
Martin Preuss
26cc4235be c03: added LIGHT value, removed LEDTIMING and BEEPERTIMING 2026-04-16 23:44:26 +02:00
Martin Preuss
7054a42909 avr: added device n31. 2026-04-16 23:43:56 +02:00
Martin Preuss
b643d2bbcc c03: use brightness module and report its values. 2026-04-16 21:28:44 +02:00
Martin Preuss
0c8d812a7a avr: make brightness module ready for ATmega devices. 2026-04-16 21:28:17 +02:00
Martin Preuss
0be8ad101a avr: more documentation. 2026-04-15 00:03:57 +02:00
Martin Preuss
3e78e2cdca avr: fixed a typo. 2026-04-14 23:57:58 +02:00
Martin Preuss
1d9762c097 incremented version. 2026-04-14 23:55:19 +02:00
Martin Preuss
aed4e0800d avr: updated documentation. 2026-04-14 23:55:06 +02:00
Martin Preuss
4411162620 avr: begin preparations for using brightness module in device c03. 2026-04-14 23:54:41 +02:00
Martin Preuss
0df5c68fb3 avr: removed old lcd2/gui, replaced by lcd2/gui2. 2026-04-14 23:53:54 +02:00
Martin Preuss
7fb21a2f06 avr: fixed call for ATmega. 2026-04-14 23:50:51 +02:00
Martin Preuss
9d4e24222c avr: added device "minimal" (minimal example for a device using AqOS4Avr). 2026-04-14 23:50:29 +02:00
Martin Preuss
5ad304b988 avr: removed recv from led_simple (no need for it anymore). 2026-04-14 23:49:04 +02:00
Martin Preuss
8a9f74b0a1 avr: fixed includes.
for unknown reasons avra doesn't check #if statements correctly which
are meant to protect against double includes...
2026-04-14 23:47:21 +02:00
Martin Preuss
6b0ea55b3d avr: fixed includes. 2026-04-14 23:46:07 +02:00
Martin Preuss
ab7e28a9d5 avr: more code sharing. 2026-04-14 23:45:32 +02:00
Martin Preuss
d6e731b34e c03: removed old main firmware folder, make "test" folder new main. 2026-04-13 17:43:08 +02:00
Martin Preuss
a9dabf0eae gui2: fixed a bug. 2026-04-13 17:26:23 +02:00
Martin Preuss
830a25aff7 Revert "sensorwatch: added averaging."
This reverts commit f555bf7cd6.
2026-04-13 13:35:27 +02:00
Martin Preuss
ae2aef8743 added README. 2026-04-13 13:35:19 +02:00
Martin Preuss
f555bf7cd6 sensorwatch: added averaging. 2026-04-13 13:35:08 +02:00
Martin Preuss
7a58c4a8ad gui2: more code sharing. 2026-04-13 10:56:07 +02:00
Martin Preuss
0da8170df7 beeper_simple: remove msg receiption.
not needed for a beeper.
2026-04-13 00:22:29 +02:00
Martin Preuss
c4911a05cc minor formatting. 2026-04-13 00:20:47 +02:00
Martin Preuss
fa335392af avr: improved beeper code
dont start beeper already when setting timer because it might be quite some
time until the timer is called again which could make the beeper beep an
anoyingly long time.
2026-04-13 00:20:38 +02:00
Martin Preuss
f63eb308b3 avr: added a simple screen saver. 2026-04-12 23:04:25 +02:00
Martin Preuss
5fe4b4b705 gui2: renamed *layout2* to *layout* 2026-04-12 17:10:15 +02:00
Martin Preuss
98f1ab779d gui2: removed old layout modules. 2026-04-12 17:02:53 +02:00
Martin Preuss
710af679cb gui2: new layout modules basically work now. 2026-04-12 17:01:30 +02:00
Martin Preuss
505910bd12 replace MLayout with MCLayout. 2026-04-12 11:07:11 +02:00
Martin Preuss
42b7ce1814 gui2: implement OnGetDefaultWidth/Height 2026-04-12 11:03:10 +02:00
Martin Preuss
66be348ecd gui2: added mclayout (matrix layout ordering by column). 2026-04-12 01:31:23 +02:00
Martin Preuss
7d556c0f26 gui2: more work on preparing code sharing for all layout modules. 2026-04-10 00:07:53 +02:00
Martin Preuss
12cdc6c637 gui2: resize item if WIDGET_PACK_FILLED 2026-04-09 00:00:36 +02:00
Martin Preuss
b81d798008 gui2: more work on new layout module, started working on hlayout2. 2026-04-08 23:54:31 +02:00
Martin Preuss
2a5f09e239 gui2: added OBJ_CountDirectChildren 2026-04-08 23:54:05 +02:00
Martin Preuss
9da5f71ce1 gui2: added Widget_GetBorderAndSpacing 2026-04-08 23:53:51 +02:00
Martin Preuss
f0df0219a5 avr: fixed a call. 2026-04-08 23:53:33 +02:00
Martin Preuss
87c2314c2d avr: started working on another iteration of the layout modules.
This will become a base module for other layout modules (like hlayout,
vlayout and mlayout). All those modules will share the playment code.
2026-04-07 23:57:28 +02:00
Martin Preuss
5a9bff2d0b c03: more work on climate and netstats windows. 2026-04-07 23:56:14 +02:00
Martin Preuss
d7074388e6 avr: added netstats window
There seems to be a problem with MLayout (writes imaginary row at
screen Y position 0 for unknown reasons).
2026-04-06 19:02:59 +02:00
Martin Preuss
b00f697582 avr: added MainWindow_GetFirstChildOfContentWidget 2026-04-06 19:01:32 +02:00
Martin Preuss
e5dafccb29 avr: added ValueLabel_SetValue 2026-04-06 19:01:17 +02:00
Martin Preuss
0e501274eb c03: removed test code. 2026-04-06 01:56:54 +02:00
Martin Preuss
5c2f7496c3 c03: removed main menu again (use full window for that). 2026-04-06 01:55:09 +02:00
Martin Preuss
1540f62d04 c03: added main menu. 2026-04-06 01:54:24 +02:00
Martin Preuss
cc4696d408 c03: use RESSSOURCE_TXT_AQHOME 2026-04-06 01:53:18 +02:00
Martin Preuss
6176908c54 c03: use RESSSOURCE_IMG_ARROWBACK 2026-04-06 01:53:01 +02:00
Martin Preuss
6ad7bae155 c03: added ressource RESSSOURCE_TXT_AQHOME 2026-04-06 01:52:44 +02:00
Martin Preuss
487cd13297 c03, gui2: new GUI now basically works. 2026-04-06 01:45:56 +02:00
Martin Preuss
69daa1465b another name change. 2026-03-30 21:53:26 +02:00
Martin Preuss
509ec83661 test commit. 2026-03-30 21:52:17 +02:00
Martin Preuss
95197429ab fixed device description. 2026-03-30 00:19:22 +02:00
Martin Preuss
f7a66d6d81 n30: for code size reduction we don't use stats app. But we need to send DEVICE msg. 2026-03-30 00:19:05 +02:00
Martin Preuss
47894e6d89 remove unneeded files. 2026-03-30 00:18:31 +02:00
Martin Preuss
4b7c33f43e changed repository name. 2026-03-28 21:55:43 +01:00
Martin Preuss
612013f400 some docu work. 2026-03-28 21:43:38 +01:00
Martin Preuss
ca1c5c0cb9 remove unneeded file. 2026-03-28 21:43:28 +01:00
Martin Preuss
95e4de1f33 remove old files. 2026-03-28 21:40:51 +01:00
Martin Preuss
fc020088f4 fixed formatting problems. 2026-03-28 18:09:22 +01:00
Martin Preuss
f567630aaa fixed formatting errors. 2026-03-28 18:07:47 +01:00
Martin Preuss
28f64a68e6 add links to example nodes. 2026-03-28 18:06:10 +01:00
Martin Preuss
bc79d72077 integrate images into README.md 2026-03-28 17:58:01 +01:00
Martin Preuss
ee74f59563 doc: added images to README.md 2026-03-28 17:48:32 +01:00
Martin Preuss
66f061be80 doc: added descriptions and images for current nodes n29-n30. 2026-03-28 17:44:04 +01:00
Martin Preuss
82d877d5e3 fixed READMEs. 2026-03-28 17:43:33 +01:00
Martin Preuss
59d1ef7666 added warning for when firmware gets to big thus overwriting bootloader. 2026-03-28 17:43:08 +01:00
Martin Preuss
6ea1e97835 n30: fixed LED position. 2026-03-28 02:11:33 +01:00
Martin Preuss
a7ddcd2c81 c03/test: create climate window again. 2026-03-26 21:08:20 +01:00
Martin Preuss
aba71f73e0 n30: added a warning message if to much code. 2026-03-26 21:07:49 +01:00
Martin Preuss
66bc71b2bd sk6812: minor reorganizing. works now with newer BTF LED stripes. 2026-03-26 21:07:22 +01:00
Martin Preuss
02a43398a9 added VALUE_ID_LED_TYPE 2026-03-26 21:06:30 +01:00
Martin Preuss
915e525daf avr: fixed includes for sk6812 module. 2026-03-26 21:05:43 +01:00
Martin Preuss
34b6bab711 avr: added README 2026-03-26 21:05:06 +01:00
Martin Preuss
c2dcd94c14 fixed a typo. 2026-03-26 21:04:53 +01:00
Martin Preuss
bd2d5afcb5 incremented version. 2026-03-25 20:46:51 +01:00
Martin Preuss
32a2193074 n30: add value "RGBWTYPE" 2026-03-25 20:46:43 +01:00
Martin Preuss
f1d67027fa sk6812: added SetValueType. 2026-03-25 20:46:15 +01:00
Martin Preuss
0c810a7842 sk6812: read and write led strip type. 2026-03-25 20:45:50 +01:00
Martin Preuss
946fdfe39e n30: decrease ridge height. 2026-03-25 20:45:05 +01:00
Martin Preuss
ab9c377a25 fixed a typo. 2026-03-25 20:44:48 +01:00
Martin Preuss
a0a28aec45 apps_motion: report motion sensor change also via LED_Simple module. 2026-03-24 23:16:10 +01:00
Martin Preuss
d2cbca9d5a use a default repeat value (setValue will be removed from LED_Simple module). 2026-03-24 23:15:16 +01:00
Martin Preuss
67be74d2ac avr: move timing control from ma_light to sk6812.
This allows for better control over the LED strip. We can now trigger the
LED strip externally (e.g. by setting a new RGBW value).
2026-03-24 23:13:28 +01:00
Martin Preuss
42874f27cd aqhome-tool: fixed a bug. 2026-03-24 23:11:00 +01:00
Martin Preuss
c988876c79 network: only call led code if module activated. 2026-03-24 18:25:08 +01:00
Martin Preuss
c6510f10bf network: let LED temporarily enter ID mode when receiving PING.
this can be used to identify nodes on the network.
2026-03-24 18:19:12 +01:00
Martin Preuss
e23bfde746 led_simple: improved module, added repeats, id mode and activity mode.
modes:
- heartbeat mode (as before)
- id mode (slowly blink for 30s after receiving PING)
- activity mode (short blink to signal e.g. network activity)
The latter two modes fallback to heartbeat mode after some time.
2026-03-24 18:18:02 +01:00
Martin Preuss
07a6c5a540 gui2: finalized mlayout module. 2026-03-23 23:20:13 +01:00
Martin Preuss
0015a0a06c gui2: mlayout works now (in column mode)! 2026-03-23 23:15:38 +01:00
Martin Preuss
e125c4b027 test WIDGET_PACK_FILLED with MLAYOUT. 2026-03-23 22:20:42 +01:00
Martin Preuss
8eed88394f gui2: X-layout works now! 2026-03-23 22:20:11 +01:00
Martin Preuss
b9e40f236e gui2: bug hunt... 2026-03-23 00:22:45 +01:00
Martin Preuss
68624e92e0 added tests for gui2. 2026-03-23 00:22:21 +01:00
Martin Preuss
41d60f4331 added DEBUG4. 2026-03-23 00:22:08 +01:00
Martin Preuss
a727d600f1 label: enabled border drawing. 2026-03-23 00:21:25 +01:00
Martin Preuss
e7c195e635 gui2: clear CF on error in input. 2026-03-23 00:21:05 +01:00
Martin Preuss
30be5b3681 gui2: fixed an important bug (was decrementing r25!) 2026-03-23 00:20:36 +01:00
Martin Preuss
bd5a51b4d2 mlayout: works for first row now (still WIP!) 2026-03-21 13:09:06 +01:00
Martin Preuss
1a442cfb21 modified comment. 2026-03-21 08:29:31 +01:00
Martin Preuss
4eac2a105e gui2: added OBJ_SkipObjects 2026-03-21 08:29:18 +01:00
Martin Preuss
69a16c4c0f gui2: use bigcall (code becomes too large for rjmp/rcall). 2026-03-21 08:29:06 +01:00
Martin Preuss
5e3a8f444a gui2: 2nd try for a matrix layout. 2026-03-21 08:28:23 +01:00
Martin Preuss
722528f4e1 gui2: more work on mlayout (first try) 2026-03-21 08:27:52 +01:00
Martin Preuss
2878d3aaa2 sk6812: prepare use of multiple timing types.
timing is very tight so we need an extra routine per timing type for
sending a byte to the led strip.
2026-03-21 00:40:03 +01:00
Martin Preuss
c5df904fc4 n30: decreased size of cable hole again. 2026-03-21 00:07:09 +01:00
Martin Preuss
6bb26b7c90 n30: removed mentioning of old module. 2026-03-20 22:31:47 +01:00
Martin Preuss
a0e73d5788 sk6812: fixed timing issues (works again with BTF-Lighting LED strips). 2026-03-20 22:30:41 +01:00
Martin Preuss
d877508e85 avr: share code (use Main_HandleValueMsg) 2026-03-20 22:28:58 +01:00
Martin Preuss
c2dc819aec avr: fixed comments. 2026-03-20 22:28:09 +01:00
Martin Preuss
1f801c41a1 gui2: started working on matrix layout
this will later become also the base class for new implementations of
HLayout and VLayout to simplify things.
2026-03-18 01:02:11 +01:00
Martin Preuss
21b8c1fe56 minor formatting 2026-03-18 01:01:27 +01:00
Martin Preuss
440f3bcf0e c01: switched COM from old UART module to com2w 2026-03-17 00:02:13 +01:00
Martin Preuss
3bf327bb2d avr: fixed calls for 64K ATmega. 2026-03-17 00:01:23 +01:00
Martin Preuss
8085043ef6 extended memstats message and handling. 2026-03-17 00:00:38 +01:00
Martin Preuss
e6aeaabb32 e03: added network stats screen which is updated every minute. 2026-03-16 22:44:48 +01:00
Martin Preuss
70ace036a8 e02: use LED in simple blink mode. 2026-03-16 22:44:12 +01:00
Martin Preuss
1112a1bf6f avr: remove debug code (need the space) 2026-03-16 22:43:57 +01:00
Martin Preuss
f5c27d7174 lcd: remove debug code. 2026-03-16 22:43:32 +01:00
Martin Preuss
52b400d9f7 avr: adapted to latest changes. 2026-03-16 22:42:47 +01:00
Martin Preuss
fd6616c3c4 n29: minor cleanup. 2026-03-16 21:38:18 +01:00
Martin Preuss
ab77a71216 avr: added docu 2026-03-16 21:38:01 +01:00
Martin Preuss
5c18f5bf9a avr: cleanup handling of apps and modules in devices/all 2026-03-16 21:37:46 +01:00
Martin Preuss
dbb004234f increased version. 2026-03-16 18:05:13 +01:00
Martin Preuss
646c28e00a added device description files for e02 and e03. 2026-03-16 18:05:00 +01:00
Martin Preuss
47f8ef2a62 avr: started using 0.96" display on e03 2026-03-16 18:04:38 +01:00
Martin Preuss
1d39c3c773 fixed a bug (dayOfWeek starts with 0 in GWEN_TIMESTAMP, 1 in DS3231) 2026-03-16 18:04:00 +01:00
Martin Preuss
d688cd3d26 work on documentation. 2026-03-16 18:03:13 +01:00
Martin Preuss
1813c9e09e n30: decrease size of cable hole 2026-03-15 20:27:03 +01:00
Martin Preuss
274c404732 c03: remove border, use new ressource RESSSOURCE_TXT_ROOMCLIMATE 2026-03-15 20:26:43 +01:00
Martin Preuss
13a3c3a189 c03: added ressource RESSSOURCE_TXT_ROOMCLIMATE 2026-03-15 20:26:12 +01:00
Martin Preuss
8671214a2d avr: fixed apidoc 2026-03-15 20:25:50 +01:00
Martin Preuss
4140e2dc52 fixed typo 2026-03-15 20:25:35 +01:00
Martin Preuss
6a3c8b6cfa flashnode.sh: added devices e02 and e03 2026-03-15 20:25:05 +01:00
Martin Preuss
6d3a27977a avr: added time message 2026-03-15 20:24:48 +01:00
Martin Preuss
6c83991df7 avr: added NETMSG_Debug_Write2 (sends bytes from a buffer) 2026-03-15 20:23:49 +01:00
Martin Preuss
1d8b467b1d avr: added devices e02 and e03 2026-03-15 20:23:18 +01:00
Martin Preuss
a0fc10cccd aqhome-tool: added command "time" to set node network time. 2026-03-15 20:22:36 +01:00
Martin Preuss
2a76e82923 avr: activate module ds3231 2026-03-15 20:21:57 +01:00
Martin Preuss
b6f710bd8b added node message type TIME. 2026-03-15 20:21:30 +01:00
Martin Preuss
5119c38ca6 avr: added divide8 2026-03-15 20:20:33 +01:00
Martin Preuss
393df322f0 avr: added rtc module for ds3231 2026-03-15 20:20:06 +01:00
Martin Preuss
ce4a4afc68 minor formatting. 2026-03-12 16:28:43 +01:00
Martin Preuss
9d92564b2e gui2: fixed an important bug. 2026-03-12 16:28:28 +01:00
Martin Preuss
2f570ea110 gui2: more work. SensorWatch doesn't fully work, yet (also red background). 2026-03-12 00:37:44 +01:00
Martin Preuss
092c667291 gui2: fixed more bugs in layout code. Now basically works! 2026-03-11 19:53:19 +01:00
Martin Preuss
f6736c345d n30: decreases ridge height, increased height of power connection (open upper border) 2026-03-11 16:05:30 +01:00
Martin Preuss
51cedae0cb gui2: fixed problems with layouts
need to look into spread mode, too.
2026-03-11 00:32:08 +01:00
Martin Preuss
282cd738b4 gui2: started working on SensorWatch for GUI2. Works so far. 2026-03-10 00:15:52 +01:00
Martin Preuss
d3f24284ca gui2: added widgets. 2026-03-09 21:06:16 +01:00
Martin Preuss
2827f4e063 gui2: added generic button class
this gives child elements a button behavior.
2026-03-09 18:20:51 +01:00
Martin Preuss
f5e19ac0a1 gui2: removed debug code. 2026-03-09 14:03:40 +01:00
Martin Preuss
cc7f2dc1db gui2: main windows basically work now! 2026-03-09 13:56:51 +01:00
Martin Preuss
e3ae1f9b35 gui2: fixed a bug. 2026-03-09 09:14:51 +01:00
Martin Preuss
e4668378fe gui2: increase borders of label widget. 2026-03-09 09:14:39 +01:00
Martin Preuss
e24300f16b gui2: fixed a bug. 2026-03-09 09:09:03 +01:00
Martin Preuss
648b0f33c5 gui2: fixed a bug, added debug code. 2026-03-09 02:28:33 +01:00
Martin Preuss
0758579b43 gui2: more work (vlayout doesn't work, yet). 2026-03-09 02:08:33 +01:00
Martin Preuss
92efebccf1 gui2: basic start works! 2026-03-07 15:29:28 +01:00
Martin Preuss
7bd83b32b4 gui2: more code sharing. 2026-03-07 14:03:58 +01:00
Martin Preuss
3f3cdaac73 gui2: more work on gui. 2026-03-07 13:47:05 +01:00
Martin Preuss
ef3ed9df12 gui2: create root window 2026-03-07 01:51:40 +01:00
Martin Preuss
ffde6b0ddb gui2: added MainWindow_GetContentWidget. 2026-03-07 01:29:13 +01:00
Martin Preuss
f88745c3fd gui2: added default Layout handler to widget class. 2026-03-07 01:17:38 +01:00
Martin Preuss
283738f4f3 gui2: more work on layouting. 2026-03-07 01:13:02 +01:00
Martin Preuss
2cf4e414d2 gui2: more work on layout code. 2026-03-07 00:44:56 +01:00
Martin Preuss
0af5aed2f6 gui2: started working on autolayout. 2026-03-07 00:04:36 +01:00
Martin Preuss
a8cb442502 gui2: improved signal handling, make use of secondary signal maps. 2026-03-06 16:00:14 +01:00
Martin Preuss
16b820fae1 n30: adjusted enclosure
- decreased length, adjusted pos of LED hole
- decreased ridge_height
- increased power connection height
- decreased size of cable hole
2026-03-06 00:27:35 +01:00
Martin Preuss
261ddba7c4 gui2: added RootWindow_SetApp 2026-03-04 23:35:18 +01:00
Martin Preuss
ae137efb26 gui2: started working on GuiApp, MainWindow, RootWindow 2026-03-04 23:26:37 +01:00
Martin Preuss
afdd52eaf6 gui2: reorganized init/alloc code, added Widget_Resize, Widget_Move 2026-03-04 23:26:05 +01:00
Martin Preuss
0081c33c00 gui2: added Object_Alloc, OBJ_GetRoot 2026-03-04 23:25:12 +01:00
Martin Preuss
8c59b92100 minor formatting. 2026-03-04 23:24:24 +01:00
Martin Preuss
e6e1bf0535 minor formatting. 2026-03-04 00:08:35 +01:00
Martin Preuss
fe8681292f added Widget_OnDraw and Widget_OnDrawNop 2026-03-04 00:08:10 +01:00
Martin Preuss
1edd34fb5a added OBJ_GetChildAt 2026-03-04 00:07:48 +01:00
Martin Preuss
f496e6587b started working on C03 test firmware to test new gui2 module. 2026-03-03 23:52:25 +01:00
Martin Preuss
0d6bbd1147 gui2: started working on a SDRAM based GUI implementation. 2026-03-03 23:51:52 +01:00
Martin Preuss
639136431b incremented version number. 2026-03-03 23:50:35 +01:00
Martin Preuss
5692e65627 removed old nodes from flasher tool. 2026-03-01 21:51:50 +01:00
Martin Preuss
baadca7c95 added missing files. 2026-03-01 21:48:18 +01:00
Martin Preuss
43d03b0ace c03: added local TODO file. 2026-03-01 21:48:04 +01:00
Martin Preuss
d8558015b2 removed old code.
aqhome-storage has long been incorporated into aqhome-data.
2026-03-01 21:47:44 +01:00
Martin Preuss
1be66e6c7a aqhome-cgi: fixed a bug. 2026-03-01 21:46:38 +01:00
Martin Preuss
8597f89227 aqhome-cgi: added missing files. 2026-03-01 21:46:23 +01:00
Martin Preuss
d2533f66af n29: add enclosures to build files, add type-2 enclosure for n29
type-2 enclosure is without holes for motion detector and photo led.
2026-03-01 20:48:50 +01:00
Martin Preuss
0b71b9dff7 add enclosure.scad to build file. 2026-03-01 20:47:41 +01:00
Martin Preuss
717c9467a8 uncomment value. 2026-03-01 01:09:29 +01:00
Martin Preuss
b02ae49484 added .gitignore 2026-03-01 01:09:17 +01:00
Martin Preuss
69420d9c7d added device n30. 2026-03-01 01:09:04 +01:00
Martin Preuss
bdd2d3bdc6 added doc folder with first example circuit. 2026-03-01 01:06:20 +01:00
Martin Preuss
d6e87aeba5 eventloop_select: introduce error variable
abort process if too many select errors. Prevents error logs from
filling log partition.

after 90 select errors the log level will be increased for the next calls.
after 100 select errors the process aborts (will be restarted by systemd).

TODO: inspect sockets to find the bad one.
2026-02-26 23:18:55 +01:00
Martin Preuss
56f2cf6870 minor changes on enclosure for N29 devices.
- decreased height of holding ridge (was a bit tight)
- moved drilling holes in lid (the lower one was conflicting with the
  network connectors)
2026-02-26 17:35:15 +01:00
Martin Preuss
bf8f584a4a add support for n29. 2026-02-16 01:14:50 +01:00
Martin Preuss
b1efa104f0 add missing parts for e01. 2026-02-16 01:14:39 +01:00
Martin Preuss
5fc3916457 avr: started work on com2w_router for S03. 2026-02-16 01:12:25 +01:00
Martin Preuss
1b0519437c increased version. 2026-02-16 01:11:55 +01:00
Martin Preuss
9e5fd0bf8c add support for e01. 2026-02-16 01:11:40 +01:00
Martin Preuss
e117153622 add device file for n29. 2026-02-16 01:11:27 +01:00
Martin Preuss
00bea4d9f6 s03: use 16MHz clock (should work with 3V3). 2026-02-16 01:10:49 +01:00
Martin Preuss
f7475b0b31 avr: added support for 16MHz clock. 2026-02-16 01:10:15 +01:00
Martin Preuss
7c37ad930b avr: updated string. 2026-02-16 01:09:50 +01:00
Martin Preuss
bfd991a768 avr: removed old GUI code, renamed gui2 to gui 2026-02-16 01:09:39 +01:00
Martin Preuss
1e8c231707 avr: remove c02, add e01 and n29 2026-02-16 01:07:09 +01:00
Martin Preuss
aef7434f9d avr: minor fixes in screensaver code. 2026-02-09 19:07:56 +01:00
Martin Preuss
b797c09f67 avr: improved apidoc 2026-02-09 19:07:34 +01:00
Martin Preuss
4fec5433b3 avr: minor changes
- save Y in GuiApp_ShowView
- fix apidoc
- change order in guiAppShowCurrent
2026-02-09 19:07:05 +01:00
Martin Preuss
05ac62ef54 formatting. 2026-02-09 19:05:50 +01:00
Martin Preuss
409205dcd7 avr: switch to iterative code for Widget_TreeMatchFlagsAndSendSignalToActive 2026-02-09 00:35:42 +01:00
Martin Preuss
599b27c7d2 avr: fixed window redrawing for main views. 2026-02-08 00:33:08 +01:00
Martin Preuss
1dd9c8de6e avr: fixed apidoc. 2026-02-07 16:19:21 +01:00
Martin Preuss
36f52a396b avr: set screen saver timeout to 10 mins. 2026-02-07 16:18:59 +01:00
Martin Preuss
28deb9c591 avr/gui2: added screen saver app
screen saver can be turned off by:
- touching and releasing the display
- specific messages (e.g. motion detection msg from other nodes)
2026-02-07 16:09:31 +01:00
Martin Preuss
39d1060334 n28 enclosure: decreased height by 1mm, increased ridge depth and height 2026-02-06 17:51:50 +01:00
Martin Preuss
38eb21869e n28: added info. 2026-02-02 21:21:05 +01:00
Martin Preuss
a8cdf6ec58 c03: use beeper module. 2026-02-02 21:20:47 +01:00
Martin Preuss
40033db235 added simple beeper module. 2026-02-02 21:20:25 +01:00
Martin Preuss
c8e5317cac aqhome-tool: fixed a bug. 2026-02-02 21:19:53 +01:00
Martin Preuss
74b4098608 ili9341: tested backlight dimming (doesn't work with my displays, either)
probably the LED pins are hardcoded with my displays. They respond neither
to PWM on the LED pin nor to ili9341 commands.
2026-01-27 20:32:38 +01:00
Martin Preuss
7411fd2a13 ili9341: added backlight handling via PWM (doesn't work with my displays).
my displays don't accept PWM...
2026-01-27 20:31:00 +01:00
Martin Preuss
4b4d44d80f com2w: don't use activity LED for now. 2026-01-27 20:29:53 +01:00
Martin Preuss
0fa44cfa4b n26: fixed pinout. 2026-01-27 20:29:26 +01:00
Martin Preuss
653e63ad34 n16: use activity LED. 2026-01-27 20:29:10 +01:00
Martin Preuss
a7cf31b1c1 minor reformatting. 2026-01-27 20:28:39 +01:00
Martin Preuss
ce240f087e c03: changed default colors for images. 2026-01-27 20:28:22 +01:00
Martin Preuss
3b5d95f8b9 c03: fixed a typo. 2026-01-27 20:27:56 +01:00
Martin Preuss
c1da37d973 c03: define backlight pin for display. 2026-01-27 20:27:43 +01:00
Martin Preuss
eba269f2e7 avr: use activity LED for door and motion sensors. 2026-01-27 20:24:44 +01:00
Martin Preuss
a4b49f8979 n28: increase hook tolerance, add ridges for fixing pcb. 2026-01-27 20:24:11 +01:00
Martin Preuss
0df67a3e0b avr: remove init code (sensorWatch now reads from eeprom). 2026-01-24 01:03:52 +01:00
Martin Preuss
fdfc040d19 avr: use macros instead of costly calls for SPI on ILI9341. 2026-01-24 01:03:31 +01:00
Martin Preuss
2085ba6bbe avr: fixed a bug. 2026-01-24 01:02:33 +01:00
Martin Preuss
9a1ca45329 avr: use RESSSOURCE_IMG_DEBUGEEPROM 2026-01-23 22:23:50 +01:00
Martin Preuss
026e9179e7 avr: fixed a bug. 2026-01-23 22:23:32 +01:00
Martin Preuss
c59cdb1470 avr: converted 48x48 icons to RLE. Added RESSSOURCE_IMG_DEBUGEEPROM 2026-01-23 22:23:17 +01:00
Martin Preuss
74f4e32767 avr: fixed two bugs. 2026-01-23 21:42:27 +01:00
Martin Preuss
b46c65837f avr: added reset button. 2026-01-23 21:42:06 +01:00
Martin Preuss
8007c8c79a avr: shortened update interval (maybe not necessary?) 2026-01-23 21:41:43 +01:00
Martin Preuss
eb30e59c13 avr: added ressource RESSSOURCE_IMG_RESET 2026-01-23 21:41:10 +01:00
Martin Preuss
2636fa8b21 fixed apidoc. 2026-01-23 21:40:42 +01:00
Martin Preuss
50eed94821 avr: added local TODO 2026-01-23 20:49:05 +01:00
Martin Preuss
b95c09ad82 avr: make climate page the main page, added eeprom browser. 2026-01-23 20:48:48 +01:00
Martin Preuss
b4969019b2 avr: added images to ressources. 2026-01-23 20:48:06 +01:00
Martin Preuss
d963458a91 avr: fixed handler for font 6x8 2026-01-23 20:47:39 +01:00
Martin Preuss
664b8a1ea5 avr: removed needed instruction. 2026-01-23 20:47:15 +01:00
Martin Preuss
be39ad0365 avr: added Widget_DrawCharAt 2026-01-23 20:46:58 +01:00
Martin Preuss
41a70a8280 avr: added Button_DefaultSignalmap 2026-01-23 20:46:32 +01:00
Martin Preuss
e4e7aeb12e avr: added HexByteToAscii, HexWordToAscii 2026-01-23 20:46:08 +01:00
Martin Preuss
604734b6e3 avr: minor changes. 2026-01-22 00:06:09 +01:00
Martin Preuss
d64157f7ef c03: implemented setdata message handling for SensorWatch
storing/restoring data from EEPROM doesn't work, yet.
2026-01-21 22:48:44 +01:00
Martin Preuss
e5a999e9b6 c03: define TLV ids for sensorWatch 2026-01-21 22:47:40 +01:00
Martin Preuss
7a4f462fa2 added to apidoc. 2026-01-21 22:47:20 +01:00
Martin Preuss
a22d774b28 aqhome-tool: setdata can now use ":" to separate bytes/words 2026-01-21 22:47:03 +01:00
Martin Preuss
faa5991024 avr: work on eeprom TLV code. 2026-01-21 22:46:18 +01:00
Martin Preuss
dbe42c5bcb sensorwatch: introduce upper and lower limits. 2026-01-21 00:56:49 +01:00
Martin Preuss
864f815d91 updated TODO 2026-01-20 00:15:21 +01:00
Martin Preuss
94092a82d9 updated TODO. 2026-01-20 00:03:30 +01:00
Martin Preuss
242c3061bf c03: removed outdated files. 2026-01-19 23:25:59 +01:00
Martin Preuss
3225350be5 c03: added network stats window, fixed some bugs. 2026-01-19 23:24:58 +01:00
Martin Preuss
041f0fad6b avr: cleanup structure of graphics apps and gui2. 2026-01-19 21:10:51 +01:00
Martin Preuss
504e7568d4 gui2: added default signal maps, create first app for c03 graphics interface. 2026-01-19 20:51:46 +01:00
Martin Preuss
0bcb3b40f7 n28: enclosure with bigger slits for closing hooks. 2026-01-19 19:10:58 +01:00
Martin Preuss
519751043d ImageView: preset correct background color. 2026-01-19 18:44:00 +01:00
Martin Preuss
7b4bac534f gui2: removed debug widgets and functions (buttons work now). 2026-01-19 18:43:40 +01:00
Martin Preuss
79dde7402f updated TODO file. 2026-01-19 18:35:45 +01:00
Martin Preuss
b1a002013a Object: ignore selector when "0" in signal map. 2026-01-19 18:35:28 +01:00
Martin Preuss
ebb20150ca ImageView: handle PRESSED flag.
needed when used as button.
2026-01-19 18:34:56 +01:00
Martin Preuss
edc291261f gui2: added Button, RootWindow. Touch now works again. 2026-01-19 18:33:36 +01:00
Martin Preuss
715c4f22c4 updated TODO. 2026-01-19 00:50:01 +01:00
Martin Preuss
7fce521671 removed implemented features from TODO 2026-01-19 00:47:49 +01:00
Martin Preuss
065d301292 avr: more work on relative coords->absolute coords 2026-01-19 00:47:32 +01:00
Martin Preuss
c578ddd1a6 avr: added texts to ressources. 2026-01-19 00:47:01 +01:00
Martin Preuss
13f682b365 avr: added sensor watches for Temp and hunidity. 2026-01-18 20:31:17 +01:00
Martin Preuss
ff5c49ad7a add entry to todo. 2026-01-18 20:02:37 +01:00
Martin Preuss
a11c5ac536 avr: added text aligning in labels. 2026-01-18 20:02:25 +01:00
Martin Preuss
fb308ba9fc minor changes. 2026-01-18 14:28:16 +01:00
Martin Preuss
b060610f3f added TODO entries. 2026-01-18 14:28:07 +01:00
Martin Preuss
34176ea2ed c03: use complete SensorWatch for CO2. 2026-01-18 14:27:51 +01:00
Martin Preuss
46afcb3ed1 avr: completed SensorWatch (now also prints value) 2026-01-18 14:27:29 +01:00
Martin Preuss
64bc199753 avr: added ValueLabel. 2026-01-18 14:27:01 +01:00
Martin Preuss
73f9273014 avr: added routines to write text from SDRAM 2026-01-18 14:26:46 +01:00
Martin Preuss
b1693168c4 fixed apidoc. 2026-01-18 14:26:11 +01:00
Martin Preuss
276fd28782 use register r25 instead of r26 (r26 is XL!) 2026-01-18 14:25:48 +01:00
Martin Preuss
e9f1aec122 avr: added itoa 2026-01-18 14:25:21 +01:00
Martin Preuss
31cce1a609 remove implemented stuff from TODO. 2026-01-18 01:00:31 +01:00
Martin Preuss
c2d1234e00 avr: most stuff for SensorWatch implemented. 2026-01-18 00:49:08 +01:00
Martin Preuss
0443032de7 avr: added widget SensorWatch
shows a pictogram for a sensor and changes background color according to
values received from a given sensor.
2026-01-18 00:36:22 +01:00
Martin Preuss
3009e9d0d0 TODO: RLE implemented. 2026-01-17 17:16:40 +01:00
Martin Preuss
a52d7dd783 avr: added Widget_OnDrawNop 2026-01-17 17:15:48 +01:00
Martin Preuss
c2489e1866 avr: more work on gui2
- decreased complexitiy by removing guicntl
- changed fonts to allow for storing bitmaps in ressource segment
- add fonts to ressources for display node c03
- added some safety features (check pointers, add magic field to objects etc)
- moved style.asm to device folder
2026-01-17 15:23:17 +01:00
Martin Preuss
20189eb1eb added local TODO 2026-01-16 16:45:31 +01:00
Martin Preuss
48d0a3f41f added README 2026-01-16 16:45:04 +01:00
Martin Preuss
21bb33f148 fixed typos. 2026-01-16 16:44:46 +01:00
Martin Preuss
0d0b1d2fc6 write images in IDX2RLE format. 2026-01-16 16:43:14 +01:00
Martin Preuss
283374b5cd avr: add support for run-length-encoded images, converted existing images
saves much ressource space especially with larger images!
2026-01-16 16:42:49 +01:00
Martin Preuss
0aa4e6846a add comment. 2026-01-16 16:41:38 +01:00
Martin Preuss
99739325df avr: take all parents pos into account when calculating abs pos
allows for positions relative to parent in widget tables.
2026-01-15 17:27:56 +01:00
Martin Preuss
55292bddf1 avr: simplify handling of object tree
- set CFLAG if pointer valid, cleared otherwise
- check for inbound NULL pointer
2026-01-15 17:26:54 +01:00
Martin Preuss
37689fbc1d gui2: more work, added image viewer. 2026-01-14 22:57:14 +01:00
Martin Preuss
99c58d13e2 add ressources, use signals for GuiApp.
makes it easier to extend.
2026-01-14 21:19:46 +01:00
Martin Preuss
10c3f3c40d more work on images on ili9341
- reading images from predefined ressources (stored at 0x8000+) works
- drawing IDX2 images within widgets works
- added some image ressources in IDX2 format
2026-01-14 00:13:02 +01:00
Martin Preuss
edb8e7b859 texts inside labels now work. 2026-01-13 00:00:19 +01:00
Martin Preuss
caa2a92722 another GUI approach, this time more generic. 2026-01-12 22:47:08 +01:00
Martin Preuss
155b9c6f52 use markdown from gitea. 2025-12-26 23:57:54 +01:00
Martin Preuss
6468ee18b9 added license. 2025-12-26 23:57:37 +01:00
Martin Preuss
5374b6f295 added text to README. 2025-12-24 22:16:45 +01:00
Martin Preuss
00c607a65b sk6812: no longer set state when setting color. 2025-12-24 22:14:57 +01:00
Martin Preuss
c3e4435b90 n28: more work on enclosure. 2025-12-24 22:14:40 +01:00
Martin Preuss
8d65dd2182 added README. 2025-12-24 22:14:11 +01:00
Martin Preuss
bf1a34b449 n28: minor redesigning of the enclosure 2025-12-20 14:30:51 +01:00
Martin Preuss
3038208eab n28: decrease enclosure width 2025-12-20 13:08:08 +01:00
643 changed files with 43430 additions and 21847 deletions

9
0BUILD
View File

@@ -2,7 +2,7 @@
<gwbuild> <gwbuild>
<project name="aqhome" version="0.0.22" so_current="0" so_age="0" so_revision="22" write_config_h="TRUE"> <project name="aqhome" version="0.4.1" so_current="5" so_age="4" so_revision="1" write_config_h="TRUE">
<setVar name="package">$(project_name)</setVar> <setVar name="package">$(project_name)</setVar>
<setVar name="version"> <setVar name="version">
$(project_vmajor).$(project_vminor).$(project_vpatchlevel) $(project_vmajor).$(project_vminor).$(project_vpatchlevel)
@@ -180,6 +180,7 @@
devices devices
etc etc
scripts scripts
doc
</subdirs> </subdirs>
<ifVarMatches name="option_with_avr" value="TRUE" > <ifVarMatches name="option_with_avr" value="TRUE" >
@@ -256,4 +257,10 @@
</project> </project>
<extradist>
COPYING
README.md
</extradist>
</gwbuild> </gwbuild>

344
COPYING Normal file
View File

@@ -0,0 +1,344 @@
License
=======
The following is the license text for the GPL in a version that applies to
AqHome.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
<https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Moe Ghoul>, 1 April 1989
Moe Ghoul, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

82
README.md Normal file
View File

@@ -0,0 +1,82 @@
# Aquamaniac Home Control System (AqHomeControl)
## Quickstart
### Prerequisites
To compile the project the following software needs to be installed:
- gwenhywfar (general purpose library, also containing some development tools)
- avrasm (Opensource avr assembler)
- gcc (GNU C compiler)
### Building
- download and unpack this project
- cd into the main folder
- create a build folder (e.g. "mkdir build")
- cd into that "build" folder
- configure package for building ("gwbuild -s ../")
- build autogenerated files ("gwbuild -p" and "gwbuild -Btm2builder")
- build project ("gwbuild -j NUM_OF_CPUS")
- install project ("sudo gwbuild -i")
## Overview
See https://gitea.aqbanking.de/martin/aqhomecontrol/wiki for more information (in German).
The Aquamaniac Home automation/control system consists of multiple parts:
- nodes
- small PCBs with AVR microcontrollers, for now:
- AtTiny84
- AtTiny85
- AtTiny841
- AtMega644
- examples:
- [N28](https://gitea.aqbanking.de/martin/aqhomecontrol/src/branch/master/doc/mcu-examples/n28/)
- [N29](https://gitea.aqbanking.de/martin/aqhomecontrol/src/branch/master/doc/mcu-examples/n29/)
- [N30](https://gitea.aqbanking.de/martin/aqhomecontrol/src/branch/master/doc/mcu-examples/n30/)
- decentralized, nodes just broadcast measured data over a two-wire
communication network (clock/data), addresses are auto-assigned, no prior
setup necessary, no central bottleneck or single point of failure
- node types
- environmental measuring (temperature, humidity, CO2 and others)
- motion detection, door/window sensors
- LED strip controllers
- modular operating system written in AVR assembler
- event-driven GUI for ATmega MCUs (work in progress)
- driver modules for busses:
- one-wire bus
- two-wire-bus
- SPI bus
- UART
- driver modules for devices/sensors (incomplete list):
- DS18b20 sensors for temperature measurement
- SI7021 sensors for temperature and humidity measurement
- SGP_30 sensors for air quality measurement
- ccs811 sensors for air quality measurement
- SK6812 LED driver
- ds3231 realtime clock module
- I2C displays (work-in-progress)
- SPI displays (work-in-progress)
- PC applications
- aqhome-data
- TCP data service receiving sensor data
- aqhome-nodes
- service receiving sensor data via inter-node bus from nodes
and forwarding that data to aqhome-data
- aqhome-mqttlog
- service exchanging data between aqhome-data service and a
mqtt server
- aqhome-react
- service reacting to data received by aqhome-data (home automation service)
- aqhome-tool
- tool to manipulate aqhome-data (e.g. edit devices and values,
add data points, create graphs from aqhome-data)
- tool to flash firmware for nodes, list nodes
- aqhome-cgi
- HTTP service for user interaction with aqhome-data

View File

@@ -51,7 +51,6 @@
<useTargets> <useTargets>
aqhomecgi aqhomecgi
aqhcgi_service
aqhome aqhome
</useTargets> </useTargets>
@@ -121,7 +120,6 @@
<useTargets> <useTargets>
aqhome aqhome
aqhcgi_service
aqhcgi_modules aqhcgi_modules
</useTargets> </useTargets>
@@ -133,7 +131,6 @@
</libraries> </libraries>
<subdirs> <subdirs>
service
modules modules
</subdirs> </subdirs>

View File

@@ -38,7 +38,7 @@
*/ */
static void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles, const char *sBaseUrl); static void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles, const char *sBaseUrl);
static int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles); static int _handlePath(AQCGI_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles);
static void logStart(void); static void logStart(void);
static int _init(const char *sPathRuntimeFiles, const char *sBaseUrl); static int _init(const char *sPathRuntimeFiles, const char *sBaseUrl);
@@ -126,25 +126,26 @@ int main(int argc, char **argv)
void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles, const char *sBaseUrl) void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles, const char *sBaseUrl)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
int rv; int rv;
sv=AQH_ServiceFiles_new(sPathRuntimeFiles, sBaseUrl); sv=AQH_ServiceFiles_new(sPathRuntimeFiles, sBaseUrl);
AQCGI_Service_SetLoginUrl(sv, "/aqhome/login");
rv=_handlePath(sv, rq, sPathStaticFiles); rv=_handlePath(sv, rq, sPathStaticFiles);
if (rv<0) { if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv); DBG_INFO(NULL, "here (%d)", rv);
} }
AQH_Service_free(sv); AQCGI_Service_free(sv);
} }
int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles) int _handlePath(AQCGI_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles)
{ {
AQH_MODULE *mRoot; AQCGI_MODULE *mRoot;
AQH_MODULE *mParent; AQCGI_MODULE *mParent;
AQH_SESSION *session; AQCGI_SESSION *session;
const GWEN_STRINGLIST *sl; const GWEN_STRINGLIST *sl;
mRoot=AQH_ModRoot_new(sv, sPathStaticFiles); mRoot=AQH_ModRoot_new(sv, sPathStaticFiles);
@@ -165,13 +166,13 @@ int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles
s=GWEN_StringListEntry_Data(se); s=GWEN_StringListEntry_Data(se);
if (s && *s) { if (s && *s) {
if (seNext) { if (seNext) {
AQH_MODULE *m; AQCGI_MODULE *m;
DBG_ERROR(NULL, "Entry: %s (%s)", s, seNext?"not last":"last"); DBG_ERROR(NULL, "Entry: %s (%s)", s, seNext?"not last":"last");
m=AQH_ModService_LoadSubModule(mParent, rq, session, s); m=AQH_ModService_LoadSubModule(mParent, rq, session, s);
if (m==NULL) { if (m==NULL) {
AQH_Session_free(session); AQCGI_Session_free(session);
AQH_Module_free(mRoot); AQCGI_Module_free(mRoot);
return GWEN_ERROR_GENERIC; return GWEN_ERROR_GENERIC;
} }
mParent=m; mParent=m;
@@ -184,8 +185,8 @@ int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles
rv=AQH_ModService_HandleRequest(mParent, rq, session, s); rv=AQH_ModService_HandleRequest(mParent, rq, session, s);
if (rv<0) { if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv); DBG_INFO(NULL, "here (%d)", rv);
AQH_Session_free(session); AQCGI_Session_free(session);
AQH_Module_free(mRoot); AQCGI_Module_free(mRoot);
return rv; return rv;
} }
break; break;
@@ -194,13 +195,13 @@ int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles
se=seNext; se=seNext;
} }
AQH_Session_free(session); AQCGI_Session_free(session);
AQH_Module_free(mRoot); AQCGI_Module_free(mRoot);
return 0; return 0;
} }
else { else {
AQH_Session_free(session); AQCGI_Session_free(session);
AQH_Module_free(mRoot); AQCGI_Module_free(mRoot);
return GWEN_ERROR_GENERIC; return GWEN_ERROR_GENERIC;
} }
} }
@@ -222,7 +223,7 @@ void logStart()
int _init(const char *sPathRuntimeFiles, const char *sBaseUrl) int _init(const char *sPathRuntimeFiles, const char *sBaseUrl)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
int rv; int rv;
DBG_ERROR(NULL, "Creating aqhome-cgi environment in \"%s\"", sPathRuntimeFiles); DBG_ERROR(NULL, "Creating aqhome-cgi environment in \"%s\"", sPathRuntimeFiles);
@@ -230,32 +231,32 @@ int _init(const char *sPathRuntimeFiles, const char *sBaseUrl)
rv=AQH_ModAdmin_Create(sv); rv=AQH_ModAdmin_Create(sv);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "Error creating module \"admin\""); DBG_ERROR(NULL, "Error creating module \"admin\"");
AQH_Service_free(sv); AQCGI_Service_free(sv);
return rv; return rv;
} }
rv=AQH_ModAdmModules_Create(sv); rv=AQH_ModAdmModules_Create(sv);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "Error creating module \"modules\""); DBG_ERROR(NULL, "Error creating module \"modules\"");
AQH_Service_free(sv); AQCGI_Service_free(sv);
return rv; return rv;
} }
rv=AQH_ModAdmUsers_Create(sv); rv=AQH_ModAdmUsers_Create(sv);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "Error creating module \"users\""); DBG_ERROR(NULL, "Error creating module \"users\"");
AQH_Service_free(sv); AQCGI_Service_free(sv);
return rv; return rv;
} }
rv=AQH_ModDevices_Create(sv); rv=AQH_ModDevices_Create(sv);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "Error creating module \"devices\""); DBG_ERROR(NULL, "Error creating module \"devices\"");
AQH_Service_free(sv); AQCGI_Service_free(sv);
return rv; return rv;
} }
AQH_Service_free(sv); AQCGI_Service_free(sv);
return 0; return 0;
} }

View File

@@ -6,6 +6,7 @@
<includes type="c" > <includes type="c" >
$(gwenhywfar_cflags) $(gwenhywfar_cflags)
$(aqcgi_cflags)
-I$(topsrcdir) -I$(topsrcdir)
-I$(topbuilddir) -I$(topbuilddir)
-I$(topsrcdir)/apps -I$(topsrcdir)/apps

View File

@@ -6,6 +6,7 @@
<includes type="c" > <includes type="c" >
$(gwenhywfar_cflags) $(gwenhywfar_cflags)
$(aqcgi_cflags)
-I$(topsrcdir) -I$(topsrcdir)
-I$(topbuilddir) -I$(topbuilddir)
-I$(topsrcdir)/apps -I$(topsrcdir)/apps

View File

@@ -13,10 +13,11 @@
#include "./madmin.h" #include "./madmin.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/common/mmodules.h" #include "aqhome-cgi/modules/common/mmodules.h"
#include "aqhome-cgi/modules/common/musers.h" #include "aqhome-cgi/modules/common/musers.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
@@ -37,12 +38,12 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _createPermDefList(AQH_MODULE *m); static void _createPermDefList(AQCGI_MODULE *m);
static void _createRoleList(AQH_MODULE *m); static void _createRoleList(AQCGI_MODULE *m);
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); static AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName);
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); static int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem);
static int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf); static int _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf);
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -50,7 +51,7 @@ static int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf);
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModAdmin_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) void AQH_ModAdmin_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder)
{ {
AQH_ModService_Extend(m, sv, baseFolder); AQH_ModService_Extend(m, sv, baseFolder);
AQH_ModService_SetHandleRequestFn(m, _handleRequest); AQH_ModService_SetHandleRequestFn(m, _handleRequest);
@@ -59,65 +60,65 @@ void AQH_ModAdmin_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder)
int AQH_ModAdmin_Create(AQH_SERVICE *sv) int AQH_ModAdmin_Create(AQCGI_SERVICE *sv)
{ {
AQH_MODULE *m; AQCGI_MODULE *m;
int rv; int rv;
m=AQH_Module_new(); m=AQCGI_Module_new();
AQH_Module_SetName(m, "admin"); AQCGI_Module_SetName(m, "admin");
AQH_Module_SetDescr(m, "administration module"); AQCGI_Module_SetDescr(m, "administration module");
AQH_Module_SetGuestPerms(m, 0); AQCGI_Module_SetGuestPerms(m, 0);
_createPermDefList(m); _createPermDefList(m);
_createRoleList(m); _createRoleList(m);
rv=AQH_Service_AddModule(sv, m); rv=AQCGI_Service_AddModule(sv, m);
if (rv<0) { if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv); DBG_INFO(NULL, "here (%d)", rv);
} }
AQH_Module_free(m); AQCGI_Module_free(m);
return rv; return rv;
} }
void _createPermDefList(AQH_MODULE *m) void _createPermDefList(AQCGI_MODULE *m)
{ {
AQH_PERMDEF_LIST *permDefList; AQCGI_PERMDEF_LIST *permDefList;
permDefList=AQH_PermDef_List_new(); permDefList=AQCGI_PermDef_List_new();
AQH_ModService_AddPermDef(permDefList, "AdminUsers", 0x001, "User Administration"); AQH_ModService_AddPermDef(permDefList, "AdminUsers", 0x001, "User Administration");
AQH_ModService_AddPermDef(permDefList, "AdminModules", 0x002, "Module Administration"); AQH_ModService_AddPermDef(permDefList, "AdminModules", 0x002, "Module Administration");
AQH_Module_SetPermDefList(m, permDefList); AQCGI_Module_SetPermDefList(m, permDefList);
} }
void _createRoleList(AQH_MODULE *m) void _createRoleList(AQCGI_MODULE *m)
{ {
AQH_ROLE_LIST *roleList; AQCGI_ROLE_LIST *roleList;
int id=0; int id=1;
roleList=AQH_Role_List_new(); roleList=AQCGI_Role_List_new();
AQH_ModService_AddRole(roleList, id++, "userAdmin", AQH_MODADM_PERMS_ADMINUSERS, "User administrator"); AQH_ModService_AddRole(roleList, id++, "userAdmin", AQH_MODADM_PERMS_ADMINUSERS, "User administrator");
AQH_ModService_AddRole(roleList, id++, "moduleAdmin", AQH_MODADM_PERMS_ADMINMODULES, "Module administrator"); AQH_ModService_AddRole(roleList, id++, "moduleAdmin", AQH_MODADM_PERMS_ADMINMODULES, "Module administrator");
AQH_Module_SetRoleList(m, roleList); AQCGI_Module_SetRoleList(m, roleList);
} }
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
if (strcasecmp(sModuleName, "modules")==0) { if (strcasecmp(sModuleName, "modules")==0) {
AQH_MODULE *mSub; AQCGI_MODULE *mSub;
mSub=AQH_Service_LoadModule(sv, sModuleName); mSub=AQCGI_Service_LoadModule(sv, sModuleName);
if (mSub) { if (mSub) {
const char *s; const char *s;
GWEN_BUFFER *nbuf; GWEN_BUFFER *nbuf;
@@ -127,15 +128,15 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
GWEN_Buffer_AppendArgs(nbuf, "%s/modules", s?s:"."); GWEN_Buffer_AppendArgs(nbuf, "%s/modules", s?s:".");
AQH_ModAdmModules_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf)); AQH_ModAdmModules_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf));
AQH_Module_Tree2_AddChild(m, mSub); AQCGI_Module_Tree2_AddChild(m, mSub);
GWEN_Buffer_free(nbuf); GWEN_Buffer_free(nbuf);
return mSub; return mSub;
} }
} }
else if (strcasecmp(sModuleName, "users")==0) { else if (strcasecmp(sModuleName, "users")==0) {
AQH_MODULE *mSub; AQCGI_MODULE *mSub;
mSub=AQH_Service_LoadModule(sv, sModuleName); mSub=AQCGI_Service_LoadModule(sv, sModuleName);
if (mSub) { if (mSub) {
const char *s; const char *s;
GWEN_BUFFER *nbuf; GWEN_BUFFER *nbuf;
@@ -145,7 +146,7 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
GWEN_Buffer_AppendArgs(nbuf, "%s/modules", s?s:"."); GWEN_Buffer_AppendArgs(nbuf, "%s/modules", s?s:".");
AQH_ModAdmUsers_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf)); AQH_ModAdmUsers_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf));
AQH_Module_Tree2_AddChild(m, mSub); AQCGI_Module_Tree2_AddChild(m, mSub);
GWEN_Buffer_free(nbuf); GWEN_Buffer_free(nbuf);
return mSub; return mSub;
} }
@@ -155,7 +156,7 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem)
{ {
GWEN_BUFFER *dbuf; GWEN_BUFFER *dbuf;
int rv=0; int rv=0;
@@ -166,10 +167,8 @@ int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const
if (strcasecmp(sLastPathElem, "index.html")==0) { if (strcasecmp(sLastPathElem, "index.html")==0) {
if (AQH_ModService_GetUserPerms(m) & (AQH_MODADM_PERMS_ADMINUSERS | AQH_MODADM_PERMS_ADMINMODULES)) if (AQH_ModService_GetUserPerms(m) & (AQH_MODADM_PERMS_ADMINUSERS | AQH_MODADM_PERMS_ADMINMODULES))
rv=_handleRqIndex(m, rq, dbuf); rv=_handleRqIndex(m, rq, dbuf);
else { else
AQCGI_Request_SetResponseCode(rq, 403); AQH_ModService_DenyRequest(m, rq, session, dbuf);
AQCGI_Request_SetResponseText(rq, "Forbidden");
}
} }
else { else {
AQCGI_Request_SetResponseCode(rq, 404); AQCGI_Request_SetResponseCode(rq, 404);
@@ -184,7 +183,7 @@ int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const
int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf) int _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
{ {
if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) { if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) {
uint32_t userPerms; uint32_t userPerms;

View File

@@ -20,9 +20,9 @@
#define AQH_MODADM_PERMS_ADMINMODULES 0x002 #define AQH_MODADM_PERMS_ADMINMODULES 0x002
void AQH_ModAdmin_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); void AQH_ModAdmin_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder);
int AQH_ModAdmin_Create(AQH_SERVICE *sv); int AQH_ModAdmin_Create(AQCGI_SERVICE *sv);

View File

@@ -13,7 +13,7 @@
#include "./mmodules.h" #include "./mmodules.h"
#include "aqhome-cgi/service/module.h" #include "aqcgi/service/module.h"
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
@@ -35,33 +35,33 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _createPermDefList(AQH_MODULE *m); static void _createPermDefList(AQCGI_MODULE *m);
static void _createRoleList(AQH_MODULE *m); static void _createRoleList(AQCGI_MODULE *m);
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); static AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName);
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); static int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem);
static void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqEditModGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqEditModGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqEditModPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqEditModPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqAddRoleGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqAddRoleGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqAddRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqAddRolePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqEditRoleGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqEditRoleGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqEditRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqEditRolePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static int _getHighestUsedRoleId(const AQH_ROLE_LIST *roleList); static int _getHighestUsedRoleId(const AQCGI_ROLE_LIST *roleList);
static void _handleRqDeleteRole(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqDeleteRole(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _writeEditModForm(const AQH_MODULE *currentMod, const char *sModName, GWEN_BUFFER *dbuf); static void _writeEditModForm(const AQCGI_MODULE *currentMod, const char *sModName, GWEN_BUFFER *dbuf);
static void _writeRoleListToForm(const AQH_ROLE_LIST *roleList, static void _writeRoleListToForm(const AQCGI_ROLE_LIST *roleList,
const char *sModName, const char *sModName,
const AQH_PERMDEF_LIST *permDefList, const AQCGI_PERMDEF_LIST *permDefList,
GWEN_BUFFER *dbuf); GWEN_BUFFER *dbuf);
static void _setLocationHeaderForMod(AQCGI_REQUEST *rq, const char *page, const char *sModName); static void _setLocationHeaderForMod(AQCGI_REQUEST *rq, const char *page, const char *sModName);
static void _writeEnabledPermissions(const AQH_PERMDEF_LIST *permDefList, uint32_t perms, GWEN_BUFFER *dbuf); static void _writeEnabledPermissions(const AQCGI_PERMDEF_LIST *permDefList, uint32_t perms, GWEN_BUFFER *dbuf);
@@ -89,7 +89,7 @@ static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModAdmModules_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) void AQH_ModAdmModules_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder)
{ {
AQH_ModService_Extend(m, sv, baseFolder); AQH_ModService_Extend(m, sv, baseFolder);
AQH_ModService_SetHandleRequestFn(m, _handleRequest); AQH_ModService_SetHandleRequestFn(m, _handleRequest);
@@ -98,63 +98,63 @@ void AQH_ModAdmModules_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFo
int AQH_ModAdmModules_Create(AQH_SERVICE *sv) int AQH_ModAdmModules_Create(AQCGI_SERVICE *sv)
{ {
AQH_MODULE *m; AQCGI_MODULE *m;
int rv; int rv;
m=AQH_Module_new(); m=AQCGI_Module_new();
AQH_Module_SetName(m, "modules"); AQCGI_Module_SetName(m, "modules");
AQH_Module_SetDescr(m, "modules administration module"); AQCGI_Module_SetDescr(m, "modules administration module");
AQH_Module_SetGuestPerms(m, 0); AQCGI_Module_SetGuestPerms(m, 0);
_createPermDefList(m); _createPermDefList(m);
_createRoleList(m); _createRoleList(m);
rv=AQH_Service_AddModule(sv, m); rv=AQCGI_Service_AddModule(sv, m);
if (rv<0) { if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv); DBG_INFO(NULL, "here (%d)", rv);
} }
AQH_Module_free(m); AQCGI_Module_free(m);
return rv; return rv;
} }
void _createPermDefList(AQH_MODULE *m) void _createPermDefList(AQCGI_MODULE *m)
{ {
AQH_PERMDEF_LIST *permDefList; AQCGI_PERMDEF_LIST *permDefList;
permDefList=AQH_PermDef_List_new(); permDefList=AQCGI_PermDef_List_new();
AQH_ModService_AddPermDef(permDefList, "ModuleRead", 0x001, "Read modules"); AQH_ModService_AddPermDef(permDefList, "ModuleRead", 0x001, "Read modules");
AQH_ModService_AddPermDef(permDefList, "ModuleWrite", 0x002, "Modify modules"); AQH_ModService_AddPermDef(permDefList, "ModuleWrite", 0x002, "Modify modules");
AQH_ModService_AddPermDef(permDefList, "ModuleAdd", 0x004, "Add modules"); AQH_ModService_AddPermDef(permDefList, "ModuleAdd", 0x004, "Add modules");
AQH_ModService_AddPermDef(permDefList, "ModuleDel", 0x008, "Remove modules"); AQH_ModService_AddPermDef(permDefList, "ModuleDel", 0x008, "Remove modules");
AQH_Module_SetPermDefList(m, permDefList); AQCGI_Module_SetPermDefList(m, permDefList);
} }
void _createRoleList(AQH_MODULE *m) void _createRoleList(AQCGI_MODULE *m)
{ {
AQH_ROLE_LIST *roleList; AQCGI_ROLE_LIST *roleList;
int id=0; int id=1;
roleList=AQH_Role_List_new(); roleList=AQCGI_Role_List_new();
AQH_ModService_AddRole(roleList, id++, "admin", AQH_ModService_AddRole(roleList, id++, "admin",
AQH_MODADMMODULES_PERMS_MODULESREAD | AQH_MODADMMODULES_PERMS_MODULESREAD |
AQH_MODADMMODULES_PERMS_MODULESWRITE | AQH_MODADMMODULES_PERMS_MODULESWRITE |
AQH_MODADMMODULES_PERMS_MODULESADD | AQH_MODADMMODULES_PERMS_MODULESADD |
AQH_MODADMMODULES_PERMS_MODULESDEL, AQH_MODADMMODULES_PERMS_MODULESDEL,
"Administrator Role"); "Administrator Role");
AQH_Module_SetRoleList(m, roleList); AQCGI_Module_SetRoleList(m, roleList);
} }
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName)
{ {
/* no sub-modules */ /* no sub-modules */
return NULL; return NULL;
@@ -162,7 +162,7 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem)
{ {
AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable); AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable);
return AQCGI_SendResponse(rq); return AQCGI_SendResponse(rq);
@@ -170,15 +170,15 @@ int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const
void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_STRINGLIST *slModules; GWEN_STRINGLIST *slModules;
uint32_t perms; uint32_t perms;
perms=AQH_ModService_GetUserPerms(m); perms=AQH_ModService_GetUserPerms(m);
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
slModules=AQH_Service_ListModules(sv); slModules=AQCGI_Service_ListModules(sv);
if (slModules) { if (slModules) {
GWEN_STRINGLISTENTRY *se; GWEN_STRINGLISTENTRY *se;
@@ -195,18 +195,18 @@ void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN
sModName=GWEN_StringListEntry_Data(se); sModName=GWEN_StringListEntry_Data(se);
if (sModName && *sModName) { if (sModName && *sModName) {
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
currentMod=AQH_Service_LoadModule(sv, sModName); currentMod=AQCGI_Service_LoadModule(sv, sModName);
if (currentMod) { if (currentMod) {
const char *s; const char *s;
const char *sName; const char *sName;
sName=AQH_Module_GetName(currentMod); sName=AQCGI_Module_GetName(currentMod);
GBAS(dbuf, "<tr>"); GBAS(dbuf, "<tr>");
GBAA(dbuf, "<td>%lu</td>", (unsigned long int) AQH_Module_GetId(currentMod)); GBAA(dbuf, "<td>%lu</td>", (unsigned long int) AQCGI_Module_GetId(currentMod));
GBAA(dbuf, "<td>%s</td>", sName?sName:""); GBAA(dbuf, "<td>%s</td>", sName?sName:"");
s=AQH_Module_GetDescr(currentMod); s=AQCGI_Module_GetDescr(currentMod);
GBAA(dbuf, "<td>%s</td>", s?s:""); GBAA(dbuf, "<td>%s</td>", s?s:"");
GBAS(dbuf, "<td>"); GBAS(dbuf, "<td>");
@@ -214,7 +214,7 @@ void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN
GBAA(dbuf, "<a href=\"editmodule.html?name=%s\"><img src=\"/pics/edit.png\"></a>", sName?sName:""); GBAA(dbuf, "<a href=\"editmodule.html?name=%s\"><img src=\"/pics/edit.png\"></a>", sName?sName:"");
GBAA(dbuf, "</td>\n"); GBAA(dbuf, "</td>\n");
GBAA(dbuf, "</tr>\n"); GBAA(dbuf, "</tr>\n");
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
} }
} }
se=GWEN_StringListEntry_Next(se); se=GWEN_StringListEntry_Next(se);
@@ -230,20 +230,20 @@ void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN
void _handleRqEditModGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqEditModGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sModName; const char *sModName;
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbQuery=AQCGI_Request_GetDbQuery(rq); dbQuery=AQCGI_Request_GetDbQuery(rq);
sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "name", 0, NULL):NULL; sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "name", 0, NULL):NULL;
currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; currentMod=(sModName && *sModName)?AQCGI_Service_LoadModule(sv, sModName):NULL;
if (currentMod) { if (currentMod) {
_writeEditModForm(currentMod, sModName, dbuf); _writeEditModForm(currentMod, sModName, dbuf);
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
} }
else { else {
AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html");
@@ -254,42 +254,42 @@ void _handleRqEditModGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session,
void _handleRqEditModPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqEditModPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sModName; const char *sModName;
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbPost=AQCGI_Request_GetDbPostBody(rq); dbPost=AQCGI_Request_GetDbPostBody(rq);
sModName=dbPost?GWEN_DB_GetCharValue(dbPost, "module", 0, NULL):NULL; sModName=dbPost?GWEN_DB_GetCharValue(dbPost, "module", 0, NULL):NULL;
currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; currentMod=(sModName && *sModName)?AQCGI_Service_LoadModule(sv, sModName):NULL;
if (currentMod) { if (currentMod) {
const char *sNewModName; const char *sNewModName;
const char *sDescr; const char *sDescr;
int rv; int rv;
uint32_t perms; uint32_t perms;
const AQH_PERMDEF_LIST *permDefList; const AQCGI_PERMDEF_LIST *permDefList;
permDefList=AQH_Module_GetPermDefList(currentMod); permDefList=AQCGI_Module_GetPermDefList(currentMod);
sNewModName=GWEN_DB_GetCharValue(dbPost, "name", 0, NULL); sNewModName=GWEN_DB_GetCharValue(dbPost, "name", 0, NULL);
sDescr=GWEN_DB_GetCharValue(dbPost, "descr", 0, NULL); sDescr=GWEN_DB_GetCharValue(dbPost, "descr", 0, NULL);
perms=AQH_ModService_ReadPermsFromForm(dbPost, permDefList, NULL); perms=AQH_ModService_ReadPermsFromForm(dbPost, permDefList, NULL);
if (sNewModName && *sNewModName) if (sNewModName && *sNewModName)
AQH_Module_SetName(currentMod, sNewModName); AQCGI_Module_SetName(currentMod, sNewModName);
AQH_Module_SetDescr(currentMod, sDescr); AQCGI_Module_SetDescr(currentMod, sDescr);
AQH_Module_SetGuestPerms(currentMod, perms); AQCGI_Module_SetGuestPerms(currentMod, perms);
rv=AQH_Service_SaveModule(sv, currentMod); rv=AQCGI_Service_SaveModule(sv, currentMod);
if (rv<0) { if (rv<0) {
GBAS(dbuf, "<h2>Error</h2><p>Error saving module</p>"); GBAS(dbuf, "<h2>Error</h2><p>Error saving module</p>");
DBG_ERROR(NULL, "Could not save module \"%s\"", sModName); DBG_ERROR(NULL, "Could not save module \"%s\"", sModName);
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
return; return;
} }
DBG_ERROR(NULL, "Module \"%s\" saved", sModName); DBG_ERROR(NULL, "Module \"%s\" saved", sModName);
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html");
AQCGI_Request_SetResponseCode(rq, 303); AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See other"); AQCGI_Request_SetResponseText(rq, "See other");
@@ -302,21 +302,21 @@ void _handleRqEditModPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
void _handleRqAddRoleGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqAddRoleGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sModName; const char *sModName;
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
const AQH_PERMDEF_LIST *permDefList; const AQCGI_PERMDEF_LIST *permDefList;
uint32_t guestPerms; uint32_t guestPerms;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbQuery=AQCGI_Request_GetDbQuery(rq); dbQuery=AQCGI_Request_GetDbQuery(rq);
sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "mod", 0, NULL):NULL; sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "mod", 0, NULL):NULL;
currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; currentMod=(sModName && *sModName)?AQCGI_Service_LoadModule(sv, sModName):NULL;
guestPerms=currentMod?AQH_Module_GetGuestPerms(currentMod):0; guestPerms=currentMod?AQCGI_Module_GetGuestPerms(currentMod):0;
permDefList=currentMod?AQH_Module_GetPermDefList(currentMod):NULL; permDefList=currentMod?AQCGI_Module_GetPermDefList(currentMod):NULL;
if (currentMod) { if (currentMod) {
if (permDefList) { if (permDefList) {
@@ -340,7 +340,7 @@ void _handleRqAddRoleGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session,
GBAS(dbuf, "<p>Please add permission definitions first.</p>\n"); GBAS(dbuf, "<p>Please add permission definitions first.</p>\n");
GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:""); GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:"");
} }
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
} }
else { else {
GBAS(dbuf, "<p>Error loading module.</p>\n"); GBAS(dbuf, "<p>Error loading module.</p>\n");
@@ -350,18 +350,18 @@ void _handleRqAddRoleGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session,
void _handleRqAddRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqAddRolePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sModName; const char *sModName;
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
int newId; int newId;
const char *sName; const char *sName;
const char *sDescr; const char *sDescr;
uint32_t perms; uint32_t perms;
AQH_PERMDEF_LIST *permDefList; AQCGI_PERMDEF_LIST *permDefList;
AQH_ROLE_LIST *roleList; AQCGI_ROLE_LIST *roleList;
int rv; int rv;
/* sample data */ /* sample data */
@@ -369,9 +369,9 @@ void _handleRqAddRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbPost=AQCGI_Request_GetDbPostBody(rq); dbPost=AQCGI_Request_GetDbPostBody(rq);
sModName=dbPost?GWEN_DB_GetCharValue(dbPost, "mod", 0, NULL):NULL; sModName=dbPost?GWEN_DB_GetCharValue(dbPost, "mod", 0, NULL):NULL;
currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; currentMod=(sModName && *sModName)?AQCGI_Service_LoadModule(sv, sModName):NULL;
permDefList=currentMod?AQH_Module_GetPermDefList(currentMod):NULL; permDefList=currentMod?AQCGI_Module_GetPermDefList(currentMod):NULL;
roleList=currentMod?AQH_Module_GetRoleList(currentMod):NULL; roleList=currentMod?AQCGI_Module_GetRoleList(currentMod):NULL;
/* read role values */ /* read role values */
newId=(roleList?_getHighestUsedRoleId(roleList):0)+1; newId=(roleList?_getHighestUsedRoleId(roleList):0)+1;
sName=dbPost?GWEN_DB_GetCharValue(dbPost, "name", 0, NULL):NULL; sName=dbPost?GWEN_DB_GetCharValue(dbPost, "name", 0, NULL):NULL;
@@ -387,33 +387,33 @@ void _handleRqAddRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
} }
if (currentMod) { if (currentMod) {
AQH_ROLE *role; AQCGI_ROLE *role;
/* set new values */ /* set new values */
role=AQH_Role_new(); role=AQCGI_Role_new();
AQH_Role_SetId(role, newId); AQCGI_Role_SetId(role, newId);
AQH_Role_SetName(role, sName); AQCGI_Role_SetName(role, sName);
AQH_Role_SetDescr(role, sDescr); AQCGI_Role_SetDescr(role, sDescr);
AQH_Role_SetPerms(role, perms); AQCGI_Role_SetPerms(role, perms);
/* add role */ /* add role */
if (roleList==NULL) { if (roleList==NULL) {
roleList=AQH_Role_List_new(); roleList=AQCGI_Role_List_new();
AQH_Module_SetRoleList(currentMod, roleList); AQCGI_Module_SetRoleList(currentMod, roleList);
} }
AQH_Role_List_Add(role, roleList); AQCGI_Role_List_Add(role, roleList);
/* save module */ /* save module */
rv=AQH_Service_SaveModule(sv, currentMod); rv=AQCGI_Service_SaveModule(sv, currentMod);
if (rv<0) { if (rv<0) {
GBAS(dbuf, "<p>Error saving module.</p>\n"); GBAS(dbuf, "<p>Error saving module.</p>\n");
GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:""); GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:"");
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
return; return;
} }
_setLocationHeaderForMod(rq, "editmodule.html", sModName); _setLocationHeaderForMod(rq, "editmodule.html", sModName);
AQCGI_Request_SetResponseCode(rq, 303); AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See Other"); AQCGI_Request_SetResponseText(rq, "See Other");
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
} }
else { else {
GBAS(dbuf, "<p>Error loading module.</p>\n"); GBAS(dbuf, "<p>Error loading module.</p>\n");
@@ -423,31 +423,31 @@ void _handleRqAddRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
void _handleRqEditRoleGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqEditRoleGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sModName; const char *sModName;
int id; int id;
const char *sName; const char *sName;
const char *sDescr; const char *sDescr;
uint32_t perms; uint32_t perms;
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
const AQH_PERMDEF_LIST *permDefList; const AQCGI_PERMDEF_LIST *permDefList;
const AQH_ROLE_LIST *roleList; const AQCGI_ROLE_LIST *roleList;
const AQH_ROLE *role; const AQCGI_ROLE *role;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbQuery=AQCGI_Request_GetDbQuery(rq); dbQuery=AQCGI_Request_GetDbQuery(rq);
sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "mod", 0, NULL):NULL; sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "mod", 0, NULL):NULL;
id=dbQuery?GWEN_DB_GetIntValue(dbQuery, "id", 0, 0):0; id=dbQuery?GWEN_DB_GetIntValue(dbQuery, "id", 0, 0):0;
currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; currentMod=(sModName && *sModName)?AQCGI_Service_LoadModule(sv, sModName):NULL;
permDefList=currentMod?AQH_Module_GetPermDefList(currentMod):NULL; permDefList=currentMod?AQCGI_Module_GetPermDefList(currentMod):NULL;
roleList=currentMod?AQH_Module_GetRoleList(currentMod):NULL; roleList=currentMod?AQCGI_Module_GetRoleList(currentMod):NULL;
role=roleList?AQH_Role_List_GetById(roleList, id):NULL; role=roleList?AQCGI_Role_List_GetById(roleList, id):NULL;
sName=role?AQH_Role_GetName(role):NULL; sName=role?AQCGI_Role_GetName(role):NULL;
sDescr=role?AQH_Role_GetDescr(role):NULL; sDescr=role?AQCGI_Role_GetDescr(role):NULL;
perms=role?AQH_Role_GetPerms(role):0; perms=role?AQCGI_Role_GetPerms(role):0;
if (role) { if (role) {
GBAA(dbuf, "<h2>Edit Role for Module %s</h2>\n", sModName?sModName:""); GBAA(dbuf, "<h2>Edit Role for Module %s</h2>\n", sModName?sModName:"");
@@ -477,33 +477,33 @@ void _handleRqEditRoleGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
void _handleRqEditRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqEditRolePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sModName; const char *sModName;
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
int oldId; int oldId;
const char *sName; const char *sName;
const char *sDescr; const char *sDescr;
uint32_t perms; uint32_t perms;
AQH_PERMDEF_LIST *permDefList; AQCGI_PERMDEF_LIST *permDefList;
AQH_ROLE_LIST *roleList; AQCGI_ROLE_LIST *roleList;
AQH_ROLE *role; AQCGI_ROLE *role;
int rv; int rv;
/* sample data */ /* sample data */
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbPost=AQCGI_Request_GetDbPostBody(rq); dbPost=AQCGI_Request_GetDbPostBody(rq);
sModName=dbPost?GWEN_DB_GetCharValue(dbPost, "mod", 0, NULL):NULL; sModName=dbPost?GWEN_DB_GetCharValue(dbPost, "mod", 0, NULL):NULL;
currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; currentMod=(sModName && *sModName)?AQCGI_Service_LoadModule(sv, sModName):NULL;
permDefList=currentMod?AQH_Module_GetPermDefList(currentMod):NULL; permDefList=currentMod?AQCGI_Module_GetPermDefList(currentMod):NULL;
roleList=currentMod?AQH_Module_GetRoleList(currentMod):NULL; roleList=currentMod?AQCGI_Module_GetRoleList(currentMod):NULL;
/* read role data */ /* read role data */
oldId=dbPost?GWEN_DB_GetIntValue(dbPost, "oldId", 0, -1):-1; oldId=dbPost?GWEN_DB_GetIntValue(dbPost, "oldId", 0, -1):-1;
sName=dbPost?GWEN_DB_GetCharValue(dbPost, "name", 0, NULL):NULL; sName=dbPost?GWEN_DB_GetCharValue(dbPost, "name", 0, NULL):NULL;
sDescr=dbPost?GWEN_DB_GetCharValue(dbPost, "descr", 0, NULL):NULL; sDescr=dbPost?GWEN_DB_GetCharValue(dbPost, "descr", 0, NULL):NULL;
role=roleList?AQH_Role_List_GetById(roleList, oldId):NULL; role=roleList?AQCGI_Role_List_GetById(roleList, oldId):NULL;
perms=(dbPost && permDefList)?AQH_ModService_ReadPermsFromForm(dbPost, permDefList, NULL):0; perms=(dbPost && permDefList)?AQH_ModService_ReadPermsFromForm(dbPost, permDefList, NULL):0;
/* validate */ /* validate */
if (!(sName && *sName)) { if (!(sName && *sName)) {
@@ -521,23 +521,23 @@ void _handleRqEditRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
if (currentMod) { if (currentMod) {
/* set new values */ /* set new values */
AQH_Role_SetName(role, sName); AQCGI_Role_SetName(role, sName);
AQH_Role_SetDescr(role, sDescr); AQCGI_Role_SetDescr(role, sDescr);
AQH_Role_SetPerms(role, perms); AQCGI_Role_SetPerms(role, perms);
/* save module */ /* save module */
rv=AQH_Service_SaveModule(sv, currentMod); rv=AQCGI_Service_SaveModule(sv, currentMod);
if (rv<0) { if (rv<0) {
GBAS(dbuf, "<p>Error saving module.</p>\n"); GBAS(dbuf, "<p>Error saving module.</p>\n");
GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:""); GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:"");
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
return; return;
} }
_setLocationHeaderForMod(rq, "editmodule.html", sModName); _setLocationHeaderForMod(rq, "editmodule.html", sModName);
AQCGI_Request_SetResponseCode(rq, 303); AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See Other"); AQCGI_Request_SetResponseText(rq, "See Other");
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
} }
else { else {
GBAS(dbuf, "<p>Error loading module.</p>\n"); GBAS(dbuf, "<p>Error loading module.</p>\n");
@@ -547,36 +547,36 @@ void _handleRqEditRolePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
void _handleRqDeleteRole(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqDeleteRole(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sModName; const char *sModName;
int id; int id;
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
const AQH_ROLE_LIST *roleList; const AQCGI_ROLE_LIST *roleList;
AQH_ROLE *role; AQCGI_ROLE *role;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbQuery=AQCGI_Request_GetDbQuery(rq); dbQuery=AQCGI_Request_GetDbQuery(rq);
sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "mod", 0, NULL):NULL; sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "mod", 0, NULL):NULL;
id=dbQuery?GWEN_DB_GetIntValue(dbQuery, "id", 0, 0):0; id=dbQuery?GWEN_DB_GetIntValue(dbQuery, "id", 0, 0):0;
currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; currentMod=(sModName && *sModName)?AQCGI_Service_LoadModule(sv, sModName):NULL;
if (currentMod) { if (currentMod) {
roleList=currentMod?AQH_Module_GetRoleList(currentMod):NULL; roleList=currentMod?AQCGI_Module_GetRoleList(currentMod):NULL;
role=roleList?AQH_Role_List_GetById(roleList, id):NULL; role=roleList?AQCGI_Role_List_GetById(roleList, id):NULL;
if (role) { if (role) {
int rv; int rv;
AQH_Role_List_Del(role); AQCGI_Role_List_Del(role);
AQH_Role_free(role); AQCGI_Role_free(role);
/* save module */ /* save module */
rv=AQH_Service_SaveModule(sv, currentMod); rv=AQCGI_Service_SaveModule(sv, currentMod);
if (rv<0) { if (rv<0) {
GBAS(dbuf, "<p>Error saving module.</p>\n"); GBAS(dbuf, "<p>Error saving module.</p>\n");
GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:""); GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:"");
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
return; return;
} }
@@ -588,7 +588,7 @@ void _handleRqDeleteRole(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session,
GBAS(dbuf, "<p>Role not found.</p>\n"); GBAS(dbuf, "<p>Role not found.</p>\n");
GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:""); GBAA(dbuf, "<p><a href=\"editmodule.html?name=\"%s\"> back to module</p>\n", sModName?sModName:"");
} }
AQH_Module_free(currentMod); AQCGI_Module_free(currentMod);
} }
else { else {
GBAS(dbuf, "<p>Error loading module.</p>\n"); GBAS(dbuf, "<p>Error loading module.</p>\n");
@@ -610,20 +610,20 @@ void _setLocationHeaderForMod(AQCGI_REQUEST *rq, const char *page, const char *s
int _getHighestUsedRoleId(const AQH_ROLE_LIST *roleList) int _getHighestUsedRoleId(const AQCGI_ROLE_LIST *roleList)
{ {
int id=0; int id=0;
if (roleList) { if (roleList) {
const AQH_ROLE *role; const AQCGI_ROLE *role;
role=AQH_Role_List_First(roleList); role=AQCGI_Role_List_First(roleList);
while(role) { while(role) {
int rid; int rid;
rid=AQH_Role_GetId(role); rid=AQCGI_Role_GetId(role);
id=(rid>id)?rid:id; id=(rid>id)?rid:id;
role=AQH_Role_List_Next(role); role=AQCGI_Role_List_Next(role);
} }
} }
return id; return id;
@@ -631,17 +631,17 @@ int _getHighestUsedRoleId(const AQH_ROLE_LIST *roleList)
void _writeEditModForm(const AQH_MODULE *currentMod, const char *sModName, GWEN_BUFFER *dbuf) void _writeEditModForm(const AQCGI_MODULE *currentMod, const char *sModName, GWEN_BUFFER *dbuf)
{ {
const char *sName; const char *sName;
const char *sDescr; const char *sDescr;
const AQH_PERMDEF_LIST *permDefList; const AQCGI_PERMDEF_LIST *permDefList;
const AQH_ROLE_LIST *roleList; const AQCGI_ROLE_LIST *roleList;
permDefList=AQH_Module_GetPermDefList(currentMod); permDefList=AQCGI_Module_GetPermDefList(currentMod);
roleList=AQH_Module_GetRoleList(currentMod); roleList=AQCGI_Module_GetRoleList(currentMod);
sName=AQH_Module_GetName(currentMod); sName=AQCGI_Module_GetName(currentMod);
sDescr=AQH_Module_GetDescr(currentMod); sDescr=AQCGI_Module_GetDescr(currentMod);
/* write module info */ /* write module info */
GBAS(dbuf, "<h2>Module Info</h2>\n"); GBAS(dbuf, "<h2>Module Info</h2>\n");
GBAA(dbuf, GBAA(dbuf,
@@ -653,7 +653,7 @@ void _writeEditModForm(const AQH_MODULE *currentMod, const char *sModName, GWEN_
if (permDefList) { if (permDefList) {
GBAA(dbuf, "<tr><td><label>Guest Permissions:</label></td>\n<td>"); GBAA(dbuf, "<tr><td><label>Guest Permissions:</label></td>\n<td>");
AQH_ModService_WritePermsToForm(AQH_Module_GetGuestPerms(currentMod), permDefList, NULL, dbuf); AQH_ModService_WritePermsToForm(AQCGI_Module_GetGuestPerms(currentMod), permDefList, NULL, dbuf);
GBAA(dbuf, "</td></tr>"); GBAA(dbuf, "</td></tr>");
} }
@@ -673,36 +673,36 @@ void _writeEditModForm(const AQH_MODULE *currentMod, const char *sModName, GWEN_
void _writeRoleListToForm(const AQH_ROLE_LIST *roleList, void _writeRoleListToForm(const AQCGI_ROLE_LIST *roleList,
const char *sModName, const char *sModName,
const AQH_PERMDEF_LIST *permDefList, const AQCGI_PERMDEF_LIST *permDefList,
GWEN_BUFFER *dbuf) GWEN_BUFFER *dbuf)
{ {
const AQH_ROLE *role; const AQCGI_ROLE *role;
GBAS(dbuf, GBAS(dbuf,
"<table class=\"datatable\">\n" "<table class=\"datatable\">\n"
"<thead><tr><th>Id</th><th>Name</th><th>Permissions</th><th>Description</th><th>Actions</th></tr>\n</thead>\n" "<thead><tr><th>Id</th><th>Name</th><th>Permissions</th><th>Description</th><th>Actions</th></tr>\n</thead>\n"
"<tbody>\n"); "<tbody>\n");
role=AQH_Role_List_First(roleList); role=AQCGI_Role_List_First(roleList);
while(role) { while(role) {
uint8_t id; uint8_t id;
const char *s; const char *s;
GBAS(dbuf, "<tr>"); GBAS(dbuf, "<tr>");
/* id */ /* id */
id=AQH_Role_GetId(role); id=AQCGI_Role_GetId(role);
GBAA(dbuf, "<td>%d</td>", id); GBAA(dbuf, "<td>%d</td>", id);
/* name */ /* name */
s=AQH_Role_GetName(role); s=AQCGI_Role_GetName(role);
GBAA(dbuf, "<td>%s</td>", s?s:""); GBAA(dbuf, "<td>%s</td>", s?s:"");
/* permissions */ /* permissions */
GBAS(dbuf, "<td>"); GBAS(dbuf, "<td>");
if (permDefList) if (permDefList)
_writeEnabledPermissions(permDefList, AQH_Role_GetPerms(role), dbuf); _writeEnabledPermissions(permDefList, AQCGI_Role_GetPerms(role), dbuf);
GBAS(dbuf, "</td>"); GBAS(dbuf, "</td>");
/* description */ /* description */
s=AQH_Role_GetDescr(role); s=AQCGI_Role_GetDescr(role);
GBAA(dbuf, "<td>%s</td>", s?s:""); GBAA(dbuf, "<td>%s</td>", s?s:"");
/* actions */ /* actions */
GBAA(dbuf, "<td>"); GBAA(dbuf, "<td>");
@@ -711,7 +711,7 @@ void _writeRoleListToForm(const AQH_ROLE_LIST *roleList,
GBAA(dbuf, "</td>"); GBAA(dbuf, "</td>");
GBAS(dbuf, "</tr>\n"); GBAS(dbuf, "</tr>\n");
role=AQH_Role_List_Next(role); role=AQCGI_Role_List_Next(role);
} }
GBAS(dbuf, "</tbody>\n</table>\n"); GBAS(dbuf, "</tbody>\n</table>\n");
@@ -722,21 +722,21 @@ void _writeRoleListToForm(const AQH_ROLE_LIST *roleList,
void _writeEnabledPermissions(const AQH_PERMDEF_LIST *permDefList, uint32_t perms, GWEN_BUFFER *dbuf) void _writeEnabledPermissions(const AQCGI_PERMDEF_LIST *permDefList, uint32_t perms, GWEN_BUFFER *dbuf)
{ {
if (permDefList) { if (permDefList) {
const AQH_PERMDEF *permDef; const AQCGI_PERMDEF *permDef;
permDef=AQH_PermDef_List_First(permDefList); permDef=AQCGI_PermDef_List_First(permDefList);
while(permDef) { while(permDef) {
const char *s; const char *s;
uint32_t mask; uint32_t mask;
s=AQH_PermDef_GetId(permDef); s=AQCGI_PermDef_GetId(permDef);
mask=AQH_PermDef_GetMask(permDef); mask=AQCGI_PermDef_GetMask(permDef);
if (perms & mask) if (perms & mask)
GBAA(dbuf, "%s ", s?s:""); GBAA(dbuf, "%s ", s?s:"");
permDef=AQH_PermDef_List_Next(permDef); permDef=AQCGI_PermDef_List_Next(permDef);
} }
} }
} }

View File

@@ -24,9 +24,9 @@
void AQH_ModAdmModules_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); void AQH_ModAdmModules_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder);
int AQH_ModAdmModules_Create(AQH_SERVICE *sv); int AQH_ModAdmModules_Create(AQCGI_SERVICE *sv);

View File

@@ -13,9 +13,10 @@
#include "./mservice_p.h" #include "./mservice_p.h"
#include "aqhome-cgi/service/module.h" #include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/text.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
@@ -35,7 +36,6 @@
#define AQH_MOD_SERVICE_HEADERFILE "header.html" #define AQH_MOD_SERVICE_HEADERFILE "header.html"
#define AQH_MOD_SERVICE_FOOTERFILE "footer.html" #define AQH_MOD_SERVICE_FOOTERFILE "footer.html"
#define GBAS GWEN_Buffer_AppendString #define GBAS GWEN_Buffer_AppendString
#define GBAA GWEN_Buffer_AppendArgs #define GBAA GWEN_Buffer_AppendArgs
@@ -46,7 +46,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
GWEN_INHERIT(AQH_MODULE, AQH_MOD_SERVICE) GWEN_INHERIT(AQCGI_MODULE, AQH_MOD_SERVICE)
@@ -56,8 +56,8 @@ GWEN_INHERIT(AQH_MODULE, AQH_MOD_SERVICE)
*/ */
static void GWENHYWFAR_CB _freeData(void *bp, void *p); static void GWENHYWFAR_CB _freeData(void *bp, void *p);
static void _calcUserModPerms(AQH_MODULE *m, const AQH_USER *user); static void _calcUserModPerms(AQCGI_MODULE *m, const AQCGI_USER *user);
static uint32_t _calcRolePerms(const AQH_MODULE *m, const AQH_MODULE_PERMS *modPerms); static uint32_t _calcRolePerms(const AQCGI_MODULE *m, const AQCGI_MODULE_PERMS *modPerms);
@@ -66,12 +66,12 @@ static uint32_t _calcRolePerms(const AQH_MODULE *m, const AQH_MODULE_PERMS *modP
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModService_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) void AQH_ModService_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder)
{ {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
GWEN_NEW_OBJECT(AQH_MOD_SERVICE, xm); GWEN_NEW_OBJECT(AQH_MOD_SERVICE, xm);
GWEN_INHERIT_SETDATA(AQH_MODULE, AQH_MOD_SERVICE, m, xm, _freeData); GWEN_INHERIT_SETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m, xm, _freeData);
xm->service=sv; xm->service=sv;
xm->baseFolder=(baseFolder && *baseFolder)?strdup(baseFolder):NULL; xm->baseFolder=(baseFolder && *baseFolder)?strdup(baseFolder):NULL;
@@ -90,12 +90,12 @@ void _freeData(GWEN_UNUSED void *bp, void *p)
AQH_SERVICE *AQH_ModService_GetService(const AQH_MODULE *m) AQCGI_SERVICE *AQH_ModService_GetService(const AQCGI_MODULE *m)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
return xm->service; return xm->service;
} }
@@ -105,12 +105,12 @@ AQH_SERVICE *AQH_ModService_GetService(const AQH_MODULE *m)
const char *AQH_ModService_GetBaseFolder(const AQH_MODULE *m) const char *AQH_ModService_GetBaseFolder(const AQCGI_MODULE *m)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
return xm->baseFolder; return xm->baseFolder;
} }
@@ -120,12 +120,12 @@ const char *AQH_ModService_GetBaseFolder(const AQH_MODULE *m)
uint32_t AQH_ModService_GetUserPerms(const AQH_MODULE *m) uint32_t AQH_ModService_GetUserPerms(const AQCGI_MODULE *m)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
return xm->userPerms; return xm->userPerms;
} }
@@ -135,12 +135,12 @@ uint32_t AQH_ModService_GetUserPerms(const AQH_MODULE *m)
void AQH_ModService_SetHandleRequestFn(AQH_MODULE *m, AQH_MODSERVICE_HANDLEREQUEST_FN fn) void AQH_ModService_SetHandleRequestFn(AQCGI_MODULE *m, AQH_MODSERVICE_HANDLEREQUEST_FN fn)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
xm->handleRequestFn=fn; xm->handleRequestFn=fn;
} }
@@ -149,12 +149,12 @@ void AQH_ModService_SetHandleRequestFn(AQH_MODULE *m, AQH_MODSERVICE_HANDLEREQUE
void AQH_ModService_SetLoadSubModuleFn(AQH_MODULE *m, AQH_MODSERVICE_LOADSUBMODULE_FN fn) void AQH_ModService_SetLoadSubModuleFn(AQCGI_MODULE *m, AQH_MODSERVICE_LOADSUBMODULE_FN fn)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
xm->loadSubModuleFn=fn; xm->loadSubModuleFn=fn;
} }
@@ -163,12 +163,12 @@ void AQH_ModService_SetLoadSubModuleFn(AQH_MODULE *m, AQH_MODSERVICE_LOADSUBMODU
void AQH_ModService_SetAddHeaderFn(AQH_MODULE *m, AQH_MODSERVICE_ADDHEADER_FN fn) void AQH_ModService_SetAddHeaderFn(AQCGI_MODULE *m, AQH_MODSERVICE_ADDHEADER_FN fn)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
xm->addHeaderFn=fn; xm->addHeaderFn=fn;
} }
@@ -177,12 +177,12 @@ void AQH_ModService_SetAddHeaderFn(AQH_MODULE *m, AQH_MODSERVICE_ADDHEADER_FN fn
void AQH_ModService_SetAddFooterFn(AQH_MODULE *m, AQH_MODSERVICE_ADDFOOTER_FN fn) void AQH_ModService_SetAddFooterFn(AQCGI_MODULE *m, AQH_MODSERVICE_ADDFOOTER_FN fn)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
xm->addFooterFn=fn; xm->addFooterFn=fn;
} }
@@ -191,19 +191,19 @@ void AQH_ModService_SetAddFooterFn(AQH_MODULE *m, AQH_MODSERVICE_ADDFOOTER_FN fn
void AQH_ModService_AddHeader(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf) void AQH_ModService_AddHeader(AQCGI_MODULE *m, const char *lang, GWEN_BUFFER *dbuf)
{ {
if (m && dbuf) { if (m && dbuf) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
if (xm->addHeaderFn) if (xm->addHeaderFn)
xm->addHeaderFn(m, lang, dbuf); xm->addHeaderFn(m, lang, dbuf);
else { else {
AQH_MODULE *mParent; AQCGI_MODULE *mParent;
mParent=AQH_Module_Tree2_GetParent(m); mParent=AQCGI_Module_Tree2_GetParent(m);
if (mParent) if (mParent)
AQH_ModService_AddHeader(mParent, lang, dbuf); AQH_ModService_AddHeader(mParent, lang, dbuf);
AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_HEADERFILE, dbuf); AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_HEADERFILE, dbuf);
@@ -214,21 +214,21 @@ void AQH_ModService_AddHeader(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf
void AQH_ModService_AddFooter(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf) void AQH_ModService_AddFooter(AQCGI_MODULE *m, const char *lang, GWEN_BUFFER *dbuf)
{ {
if (m && dbuf) { if (m && dbuf) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
if (xm->addFooterFn) if (xm->addFooterFn)
xm->addFooterFn(m, lang, dbuf); xm->addFooterFn(m, lang, dbuf);
else { else {
AQH_MODULE *mParent; AQCGI_MODULE *mParent;
AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_FOOTERFILE, dbuf); AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_FOOTERFILE, dbuf);
mParent=AQH_Module_Tree2_GetParent(m); mParent=AQCGI_Module_Tree2_GetParent(m);
if (mParent) if (mParent)
AQH_ModService_AddFooter(mParent, lang, dbuf); AQH_ModService_AddFooter(mParent, lang, dbuf);
} }
@@ -238,7 +238,7 @@ void AQH_ModService_AddFooter(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf
int AQH_ModService_RespondWithFile(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *lang, const char *sFilename, GWEN_BUFFER *dbuf) int AQH_ModService_RespondWithFile(AQCGI_MODULE *m, AQCGI_REQUEST *rq, const char *lang, const char *sFilename, GWEN_BUFFER *dbuf)
{ {
int rv; int rv;
@@ -256,12 +256,40 @@ int AQH_ModService_RespondWithFile(AQH_MODULE *m, AQCGI_REQUEST *rq, const char
int AQH_ModService_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) int AQH_ModService_RespondWithVarFile(AQCGI_MODULE *m, AQCGI_REQUEST *rq,
const char *lang,
const char *sFilename,
GWEN_DB_NODE *dbVars,
GWEN_BUFFER *dbuf)
{
int rv;
GWEN_BUFFER *fbuf;
fbuf=GWEN_Buffer_new(0, 256, 0, 1);
rv=AQH_ModService_ReadStaticFile(m, lang, sFilename, fbuf);
if (rv<0) {
AQCGI_Request_SetResponseCode(rq, 500);
AQCGI_Request_SetResponseText(rq, "Internal Error");
GWEN_Buffer_free(fbuf);
return GWEN_ERROR_INTERNAL;
}
else {
GWEN_DB_ReplaceVars(dbVars, GWEN_Buffer_GetStart(fbuf), dbuf);
AQCGI_Request_SetResponseCode(rq, 200);
AQCGI_Request_SetResponseText(rq, "Ok");
GWEN_Buffer_free(fbuf);
return 0;
}
}
int AQH_ModService_HandleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm && xm->handleRequestFn) if (xm && xm->handleRequestFn)
return xm->handleRequestFn(m, rq, session, sLastPathElem); return xm->handleRequestFn(m, rq, session, sLastPathElem);
} }
@@ -270,14 +298,14 @@ int AQH_ModService_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *
AQH_MODULE *AQH_ModService_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) AQCGI_MODULE *AQH_ModService_LoadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm && xm->loadSubModuleFn) { if (xm && xm->loadSubModuleFn) {
AQH_MODULE *mReturn; AQCGI_MODULE *mReturn;
mReturn=xm->loadSubModuleFn(m, rq, session, sModuleName); mReturn=xm->loadSubModuleFn(m, rq, session, sModuleName);
if (mReturn) if (mReturn)
@@ -290,12 +318,12 @@ AQH_MODULE *AQH_ModService_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_S
int AQH_ModService_ReadStaticFile(AQH_MODULE *m, const char *lang, const char *filename, GWEN_BUFFER *dbuf) int AQH_ModService_ReadStaticFile(AQCGI_MODULE *m, const char *lang, const char *filename, GWEN_BUFFER *dbuf)
{ {
if (m && filename && dbuf) { if (m && filename && dbuf) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
GWEN_BUFFER *fbuf; GWEN_BUFFER *fbuf;
int rv; int rv;
@@ -323,9 +351,9 @@ int AQH_ModService_ReadStaticFile(AQH_MODULE *m, const char *lang, const char *f
AQH_SESSION *AQH_ModService_ReadSession(AQH_MODULE *m, AQCGI_REQUEST *rq) AQCGI_SESSION *AQH_ModService_ReadSession(AQCGI_MODULE *m, AQCGI_REQUEST *rq)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
const char *s; const char *s;
@@ -333,9 +361,9 @@ AQH_SESSION *AQH_ModService_ReadSession(AQH_MODULE *m, AQCGI_REQUEST *rq)
db=AQCGI_Request_GetDbRequestHeader(rq); db=AQCGI_Request_GetDbRequestHeader(rq);
s=GWEN_DB_GetCharValue(db, "cookies/session", 0, NULL); s=GWEN_DB_GetCharValue(db, "cookies/session", 0, NULL);
if (s && *s) { if (s && *s) {
AQH_SESSION *session; AQCGI_SESSION *session;
session=AQH_Service_LoadSession(sv, s); session=AQCGI_Service_LoadSession(sv, s);
if (session==NULL) { if (session==NULL) {
DBG_ERROR(NULL, "Session \"%s\" not found", s); DBG_ERROR(NULL, "Session \"%s\" not found", s);
return NULL; return NULL;
@@ -344,24 +372,24 @@ AQH_SESSION *AQH_ModService_ReadSession(AQH_MODULE *m, AQCGI_REQUEST *rq)
const char *sUserName; const char *sUserName;
GWEN_BUFFER *tbuf; GWEN_BUFFER *tbuf;
sUserName=AQH_Session_GetUserAlias(session); sUserName=AQCGI_Session_GetUserAlias(session);
if (sUserName && *sUserName) { if (sUserName && *sUserName) {
AQH_USER *user; AQCGI_USER *user;
user=AQH_Service_LoadUser(sv, sUserName); user=AQCGI_Service_LoadUser(sv, sUserName);
if (user==NULL) { if (user==NULL) {
DBG_ERROR(NULL, "User \"%s\" not found", sUserName); DBG_ERROR(NULL, "User \"%s\" not found", sUserName);
AQH_Session_free(session); AQCGI_Session_free(session);
return NULL; return NULL;
} }
else { else {
DBG_ERROR(NULL, "User is \"%s\"", sUserName); DBG_ERROR(NULL, "User is \"%s\"", sUserName);
} }
AQH_Session_SetUser(session, user); AQCGI_Session_SetUser(session, user);
} }
/* renew session cookie */ /* renew session cookie */
tbuf=GWEN_Buffer_new(0, 256, 0, 1); tbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(tbuf, "Set-Cookie: session=%s; max-age=86400", AQH_Session_GetUid(session)); GWEN_Buffer_AppendArgs(tbuf, "Set-Cookie: session=%s; max-age=86400", AQCGI_Session_GetUid(session));
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(tbuf)); AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(tbuf));
DBG_ERROR(NULL, "Renew session cookie"); DBG_ERROR(NULL, "Renew session cookie");
GWEN_Buffer_free(tbuf); GWEN_Buffer_free(tbuf);
@@ -376,44 +404,44 @@ AQH_SESSION *AQH_ModService_ReadSession(AQH_MODULE *m, AQCGI_REQUEST *rq)
void AQH_ModService_CalcSessionModPerms(AQH_MODULE *m, const AQH_SESSION *session) void AQH_ModService_CalcSessionModPerms(AQCGI_MODULE *m, const AQCGI_SESSION *session)
{ {
const AQH_USER *user; const AQCGI_USER *user;
user=session?AQH_Session_GetUser(session):NULL; user=session?AQCGI_Session_GetUser(session):NULL;
_calcUserModPerms(m, user); _calcUserModPerms(m, user);
} }
void _calcUserModPerms(AQH_MODULE *m, const AQH_USER *user) void _calcUserModPerms(AQCGI_MODULE *m, const AQCGI_USER *user)
{ {
if (m) { if (m) {
AQH_MOD_SERVICE *xm; AQH_MOD_SERVICE *xm;
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); xm=GWEN_INHERIT_GETDATA(AQCGI_MODULE, AQH_MOD_SERVICE, m);
if (xm) { if (xm) {
uint32_t perms=0; uint32_t perms=0;
if (user) { if (user) {
if (AQH_User_GetFlags(user) & AQH_USER_FLAGS_ADMIN) if (AQCGI_User_GetFlags(user) & AQCGI_USER_FLAGS_ADMIN)
perms=0xffffffff; perms=0xffffffff;
else { else {
const char *sModName; const char *sModName;
const AQH_MODULE_PERMS_LIST *modPermsList; const AQCGI_MODULE_PERMS_LIST *modPermsList;
AQH_MODULE_PERMS *modPerms; AQCGI_MODULE_PERMS *modPerms;
sModName=AQH_Module_GetName(m); sModName=AQCGI_Module_GetName(m);
modPermsList=AQH_User_GetModulePermList(user); modPermsList=AQCGI_User_GetModulePermList(user);
modPerms=(sModName && modPermsList)?AQH_ModulePerms_List_GetByModuleId(modPermsList, sModName):NULL; modPerms=(sModName && modPermsList)?AQCGI_ModulePerms_List_GetByModuleId(modPermsList, sModName):NULL;
if (modPerms) if (modPerms)
perms=_calcRolePerms(m, modPerms); perms=_calcRolePerms(m, modPerms);
else else
perms=AQH_Module_GetGuestPerms(m); perms=AQCGI_Module_GetGuestPerms(m);
} }
} /* if (user) */ } /* if (user) */
else else
perms=AQH_Module_GetGuestPerms(m); perms=AQCGI_Module_GetGuestPerms(m);
xm->userPerms=perms; xm->userPerms=perms;
} }
} /* if (m) */ } /* if (m) */
@@ -421,39 +449,39 @@ void _calcUserModPerms(AQH_MODULE *m, const AQH_USER *user)
uint32_t _calcRolePerms(const AQH_MODULE *m, const AQH_MODULE_PERMS *modPerms) uint32_t _calcRolePerms(const AQCGI_MODULE *m, const AQCGI_MODULE_PERMS *modPerms)
{ {
uint32_t perms=0; uint32_t perms=0;
const AQH_ROLE_LIST *roleList; const AQCGI_ROLE_LIST *roleList;
roleList=AQH_Module_GetRoleList(m); roleList=AQCGI_Module_GetRoleList(m);
if (roleList) { if (roleList) {
int roleArraySize; int roleArraySize;
int i; int i;
uint32_t explAddPerms=0; uint32_t explAddPerms=0;
uint32_t explDelPerms=0; uint32_t explDelPerms=0;
roleArraySize=AQH_ModulePerms_GetRoleArrayArraySize(); roleArraySize=AQCGI_ModulePerms_GetRoleArrayArraySize();
for (i=0; i<roleArraySize; i++) { for (i=0; i<roleArraySize; i++) {
int roleId; int roleId;
roleId=AQH_ModulePerms_GetRoleArrayAt(modPerms, i); roleId=AQCGI_ModulePerms_GetRoleArrayAt(modPerms, i);
if (roleId) { if (roleId) {
const AQH_ROLE *role; const AQCGI_ROLE *role;
role=AQH_Role_List_GetById(roleList, roleId); role=AQCGI_Role_List_GetById(roleList, roleId);
if (role) { if (role) {
perms|=AQH_Role_GetPerms(role); perms|=AQCGI_Role_GetPerms(role);
explAddPerms|=AQH_Role_GetExplAddPerms(role); explAddPerms|=AQCGI_Role_GetExplAddPerms(role);
explAddPerms|=AQH_Role_GetExplDelPerms(role); explAddPerms|=AQCGI_Role_GetExplDelPerms(role);
} }
} }
} /* for */ } /* for */
/* collate permissions */ /* collate permissions */
perms|=explAddPerms; perms|=explAddPerms;
perms|=AQH_ModulePerms_GetExplAddPerms(modPerms); perms|=AQCGI_ModulePerms_GetExplAddPerms(modPerms);
perms&=~explDelPerms; perms&=~explDelPerms;
perms&=~AQH_ModulePerms_GetExplDelPerms(modPerms); perms&=~AQCGI_ModulePerms_GetExplDelPerms(modPerms);
} }
return perms; return perms;
} }
@@ -461,36 +489,36 @@ uint32_t _calcRolePerms(const AQH_MODULE *m, const AQH_MODULE_PERMS *modPerms)
void AQH_ModService_AddPermDef(AQH_PERMDEF_LIST *permDefList, const char *id, uint32_t mask, const char *descr) void AQH_ModService_AddPermDef(AQCGI_PERMDEF_LIST *permDefList, const char *id, uint32_t mask, const char *descr)
{ {
AQH_PERMDEF *permDef; AQCGI_PERMDEF *permDef;
permDef=AQH_PermDef_new(); permDef=AQCGI_PermDef_new();
AQH_PermDef_SetId(permDef, id); AQCGI_PermDef_SetId(permDef, id);
AQH_PermDef_SetMask(permDef, mask); AQCGI_PermDef_SetMask(permDef, mask);
AQH_PermDef_SetDescr(permDef, descr); AQCGI_PermDef_SetDescr(permDef, descr);
AQH_PermDef_List_Add(permDef, permDefList); AQCGI_PermDef_List_Add(permDef, permDefList);
} }
void AQH_ModService_AddRole(AQH_ROLE_LIST *roleList, int id, const char *name, uint32_t perms, const char *descr) void AQH_ModService_AddRole(AQCGI_ROLE_LIST *roleList, int id, const char *name, uint32_t perms, const char *descr)
{ {
AQH_ROLE *role; AQCGI_ROLE *role;
role=AQH_Role_new(); role=AQCGI_Role_new();
AQH_Role_SetId(role, id); AQCGI_Role_SetId(role, id);
AQH_Role_SetName(role, name); AQCGI_Role_SetName(role, name);
AQH_Role_SetPerms(role, perms); AQCGI_Role_SetPerms(role, perms);
AQH_Role_SetDescr(role, descr); AQCGI_Role_SetDescr(role, descr);
AQH_Role_List_Add(role, roleList); AQCGI_Role_List_Add(role, roleList);
} }
void AQH_ModService_HandleRequestWithTable(AQH_MODULE *m, void AQH_ModService_HandleRequestWithTable(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
const char *page, const char *page,
const AQH_MODSERVICE_HANDLER_ENTRY *e) const AQH_MODSERVICE_HANDLER_ENTRY *e)
{ {
@@ -517,11 +545,8 @@ void AQH_ModService_HandleRequestWithTable(AQH_MODULE *m,
AQCGI_Request_SetResponseText(rq, "Ok"); AQCGI_Request_SetResponseText(rq, "Ok");
if ((perms & e[i].perms)==e[i].perms) if ((perms & e[i].perms)==e[i].perms)
(e[i].handlerFn)(m, rq, session, dbuf); (e[i].handlerFn)(m, rq, session, dbuf);
else { else
GWEN_Buffer_AppendString(dbuf, "<h1>Error</h1><p>No permissions for this request.</p>"); AQH_ModService_DenyRequest(m, rq, session, dbuf);
AQCGI_Request_SetResponseCode(rq, 403);
AQCGI_Request_SetResponseText(rq, "Forbidden");
}
break; break;
} }
} }
@@ -537,10 +562,10 @@ void AQH_ModService_HandleRequestWithTable(AQH_MODULE *m,
void AQH_ModService_WritePermsToForm(uint32_t perms, const AQH_PERMDEF_LIST *permDefList, const char *sPrefix, GWEN_BUFFER *dbuf) void AQH_ModService_WritePermsToForm(uint32_t perms, const AQCGI_PERMDEF_LIST *permDefList, const char *sPrefix, GWEN_BUFFER *dbuf)
{ {
if (permDefList) { if (permDefList) {
const AQH_PERMDEF *permDef; const AQCGI_PERMDEF *permDef;
GWEN_BUFFER *tbuf; GWEN_BUFFER *tbuf;
uint32_t pos; uint32_t pos;
@@ -549,16 +574,16 @@ void AQH_ModService_WritePermsToForm(uint32_t perms, const AQH_PERMDEF_LIST *per
GBAA(tbuf, "%s:", sPrefix); GBAA(tbuf, "%s:", sPrefix);
pos=GWEN_Buffer_GetPos(tbuf); pos=GWEN_Buffer_GetPos(tbuf);
permDef=AQH_PermDef_List_First(permDefList); permDef=AQCGI_PermDef_List_First(permDefList);
while(permDef) { while(permDef) {
const char *s; const char *s;
s=AQH_PermDef_GetId(permDef); s=AQCGI_PermDef_GetId(permDef);
if (s && *s) { if (s && *s) {
uint32_t mask; uint32_t mask;
GBAS(tbuf, s); GBAS(tbuf, s);
mask=AQH_PermDef_GetMask(permDef); mask=AQCGI_PermDef_GetMask(permDef);
if (perms & mask) if (perms & mask)
GBAA(dbuf, "<input type=\"checkbox\" name=\"%s\" checked>", GWEN_Buffer_GetStart(tbuf)); GBAA(dbuf, "<input type=\"checkbox\" name=\"%s\" checked>", GWEN_Buffer_GetStart(tbuf));
else else
@@ -566,7 +591,7 @@ void AQH_ModService_WritePermsToForm(uint32_t perms, const AQH_PERMDEF_LIST *per
GBAA(dbuf, "<label for=\"%s\">%s</label>", GWEN_Buffer_GetStart(tbuf), s?s:""); GBAA(dbuf, "<label for=\"%s\">%s</label>", GWEN_Buffer_GetStart(tbuf), s?s:"");
GWEN_Buffer_Crop(tbuf, 0, pos); GWEN_Buffer_Crop(tbuf, 0, pos);
} }
permDef=AQH_PermDef_List_Next(permDef); permDef=AQCGI_PermDef_List_Next(permDef);
} }
GWEN_Buffer_free(tbuf); GWEN_Buffer_free(tbuf);
} }
@@ -574,12 +599,12 @@ void AQH_ModService_WritePermsToForm(uint32_t perms, const AQH_PERMDEF_LIST *per
uint32_t AQH_ModService_ReadPermsFromForm(GWEN_DB_NODE *dbPost, const AQH_PERMDEF_LIST *permDefList, const char *sPrefix) uint32_t AQH_ModService_ReadPermsFromForm(GWEN_DB_NODE *dbPost, const AQCGI_PERMDEF_LIST *permDefList, const char *sPrefix)
{ {
uint32_t result=0; uint32_t result=0;
if (permDefList) { if (permDefList) {
const AQH_PERMDEF *permDef; const AQCGI_PERMDEF *permDef;
GWEN_BUFFER *tbuf; GWEN_BUFFER *tbuf;
uint32_t pos; uint32_t pos;
@@ -588,23 +613,23 @@ uint32_t AQH_ModService_ReadPermsFromForm(GWEN_DB_NODE *dbPost, const AQH_PERMDE
GBAA(tbuf, "%s:", sPrefix); GBAA(tbuf, "%s:", sPrefix);
pos=GWEN_Buffer_GetPos(tbuf); pos=GWEN_Buffer_GetPos(tbuf);
permDef=AQH_PermDef_List_First(permDefList); permDef=AQCGI_PermDef_List_First(permDefList);
while(permDef) { while(permDef) {
const char *id; const char *id;
id=AQH_PermDef_GetId(permDef); id=AQCGI_PermDef_GetId(permDef);
if (id && *id) { if (id && *id) {
uint32_t mask; uint32_t mask;
const char *s; const char *s;
GBAS(tbuf, id); GBAS(tbuf, id);
mask=AQH_PermDef_GetMask(permDef); mask=AQCGI_PermDef_GetMask(permDef);
s=GWEN_DB_GetCharValue(dbPost, GWEN_Buffer_GetStart(tbuf), 0, NULL); s=GWEN_DB_GetCharValue(dbPost, GWEN_Buffer_GetStart(tbuf), 0, NULL);
if (s && *s) if (s && *s)
result|=mask; result|=mask;
GWEN_Buffer_Crop(tbuf, 0, pos); GWEN_Buffer_Crop(tbuf, 0, pos);
} }
permDef=AQH_PermDef_List_Next(permDef); permDef=AQCGI_PermDef_List_Next(permDef);
} }
GWEN_Buffer_free(tbuf); GWEN_Buffer_free(tbuf);
} }
@@ -614,36 +639,36 @@ uint32_t AQH_ModService_ReadPermsFromForm(GWEN_DB_NODE *dbPost, const AQH_PERMDE
AQH_MODULE_LIST *AQH_ModService_LoadRawModules(AQH_MODULE *m) AQCGI_MODULE_LIST *AQH_ModService_LoadRawModules(AQCGI_MODULE *m)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_STRINGLIST *slModuleNames; GWEN_STRINGLIST *slModuleNames;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
slModuleNames=AQH_Service_ListModules(sv); slModuleNames=AQCGI_Service_ListModules(sv);
if (slModuleNames) { if (slModuleNames) {
AQH_MODULE_LIST *modList; AQCGI_MODULE_LIST *modList;
GWEN_STRINGLISTENTRY *se; GWEN_STRINGLISTENTRY *se;
modList=AQH_Module_List_new(); modList=AQCGI_Module_List_new();
se=GWEN_StringList_FirstEntry(slModuleNames); se=GWEN_StringList_FirstEntry(slModuleNames);
while(se) { while(se) {
const char *sModName; const char *sModName;
sModName=GWEN_StringListEntry_Data(se); sModName=GWEN_StringListEntry_Data(se);
if (sModName && *sModName) { if (sModName && *sModName) {
AQH_MODULE *currentMod; AQCGI_MODULE *currentMod;
currentMod=AQH_Service_LoadModule(sv, sModName); currentMod=AQCGI_Service_LoadModule(sv, sModName);
if (currentMod) if (currentMod)
AQH_Module_List_Add(currentMod, modList); AQCGI_Module_List_Add(currentMod, modList);
} }
se=GWEN_StringListEntry_Next(se); se=GWEN_StringListEntry_Next(se);
} }
GWEN_StringList_free(slModuleNames); GWEN_StringList_free(slModuleNames);
if (AQH_Module_List_GetCount(modList)) if (AQCGI_Module_List_GetCount(modList))
return modList; return modList;
AQH_Module_List_free(modList); AQCGI_Module_List_free(modList);
} }
return NULL; return NULL;
@@ -651,36 +676,36 @@ AQH_MODULE_LIST *AQH_ModService_LoadRawModules(AQH_MODULE *m)
AQH_USER_LIST *AQH_ModService_LoadRawUsers(AQH_MODULE *m) AQCGI_USER_LIST *AQH_ModService_LoadRawUsers(AQCGI_MODULE *m)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_STRINGLIST *slUserNames; GWEN_STRINGLIST *slUserNames;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
slUserNames=AQH_Service_ListUsers(sv); slUserNames=AQCGI_Service_ListUsers(sv);
if (slUserNames) { if (slUserNames) {
AQH_USER_LIST *userList; AQCGI_USER_LIST *userList;
GWEN_STRINGLISTENTRY *se; GWEN_STRINGLISTENTRY *se;
userList=AQH_User_List_new(); userList=AQCGI_User_List_new();
se=GWEN_StringList_FirstEntry(slUserNames); se=GWEN_StringList_FirstEntry(slUserNames);
while(se) { while(se) {
const char *sModName; const char *sModName;
sModName=GWEN_StringListEntry_Data(se); sModName=GWEN_StringListEntry_Data(se);
if (sModName && *sModName) { if (sModName && *sModName) {
AQH_USER *u; AQCGI_USER *u;
u=AQH_Service_LoadUser(sv, sModName); u=AQCGI_Service_LoadUser(sv, sModName);
if (u) if (u)
AQH_User_List_Add(u, userList); AQCGI_User_List_Add(u, userList);
} }
se=GWEN_StringListEntry_Next(se); se=GWEN_StringListEntry_Next(se);
} }
GWEN_StringList_free(slUserNames); GWEN_StringList_free(slUserNames);
if (AQH_User_List_GetCount(userList)) if (AQCGI_User_List_GetCount(userList))
return userList; return userList;
AQH_User_List_free(userList); AQCGI_User_List_free(userList);
} }
return NULL; return NULL;
@@ -818,3 +843,81 @@ int AQH_ModService_RespondWithMimeFile(AQCGI_REQUEST *rq, const char *sFilename,
int AQH_ModService_AddRequestUrl(const AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
{
GWEN_DB_NODE *dbRequest;
dbRequest=AQCGI_Request_GetDbRequestHeader(rq);
if (dbRequest) {
const char *s;
GWEN_Buffer_AppendArgs(dbuf,
"%s%s",
GWEN_DB_GetCharValue(dbRequest, "SCRIPT_NAME", 0, ""),
GWEN_DB_GetCharValue(dbRequest, "PATH_INFO", 0, ""));
s=GWEN_DB_GetCharValue(dbRequest, "QUERY_STRING", 0, NULL);
if (s && *s)
GWEN_Buffer_AppendArgs(dbuf, "?%s", s);
return 1;
}
return 0;
}
void AQH_ModService_Redirect(AQCGI_REQUEST *rq, const char *destLocation)
{
GWEN_BUFFER *dbuf;
dbuf=GWEN_Buffer_new(0, 128, 0, 1);
AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See other");
GWEN_Buffer_AppendArgs(dbuf, "Location: %s", destLocation);
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_free(dbuf);
}
void AQH_ModService_RedirectWithReferer(AQCGI_REQUEST *rq, const char *destLocation)
{
GWEN_BUFFER *dbuf;
GWEN_BUFFER *ubuf;
dbuf=GWEN_Buffer_new(0, 128, 0, 1);
GWEN_Buffer_AppendArgs(dbuf, "Location: %s", destLocation);
ubuf=GWEN_Buffer_new(0, 128, 0, 1);
if (AQH_ModService_AddRequestUrl(rq, ubuf)) {
DBG_ERROR(NULL, "Adding header: [%s]", GWEN_Buffer_GetStart(ubuf));
GWEN_Buffer_AppendString(dbuf, "?src=");
GWEN_Text_EscapeToBuffer(GWEN_Buffer_GetStart(ubuf), dbuf);
}
GWEN_Buffer_free(ubuf);
AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See other");
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_free(dbuf);
}
void AQH_ModService_DenyRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, const AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{
if (session && AQCGI_Session_GetUser(session)) {
/* no permissions */
AQCGI_Request_SetResponseCode(rq, 403);
AQCGI_Request_SetResponseText(rq, "Forbidden");
if (dbuf)
GWEN_Buffer_AppendString(dbuf, "<h1>Error</h1><p>No permissions for this request.</p>");
}
else {
/* need login */
AQH_ModService_RedirectWithReferer(rq, AQCGI_Service_GetLoginUrl(AQH_ModService_GetService(m)));
}
}

View File

@@ -9,9 +9,9 @@
#ifndef AQHOME_CGI_MSERVICE_H #ifndef AQHOME_CGI_MSERVICE_H
#define AQHOME_CGI_MSERVICE_H #define AQHOME_CGI_MSERVICE_H
#include <aqhome-cgi/service/module.h> #include <aqcgi/service/module.h>
#include <aqhome-cgi/service/service.h> #include <aqcgi/service/service.h>
#include <aqhome-cgi/service/session.h> #include <aqcgi/service/session.h>
#include <aqcgi/request.h> #include <aqcgi/request.h>
@@ -22,10 +22,10 @@
typedef int (*AQH_MODSERVICE_HANDLEREQUEST_FN)(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); typedef int (*AQH_MODSERVICE_HANDLEREQUEST_FN)(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem);
typedef AQH_MODULE* (*AQH_MODSERVICE_LOADSUBMODULE_FN)(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); typedef AQCGI_MODULE* (*AQH_MODSERVICE_LOADSUBMODULE_FN)(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName);
typedef void (*AQH_MODSERVICE_ADDHEADER_FN)(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf); typedef void (*AQH_MODSERVICE_ADDHEADER_FN)(AQCGI_MODULE *m, const char *lang, GWEN_BUFFER *dbuf);
typedef void (*AQH_MODSERVICE_ADDFOOTER_FN)(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf); typedef void (*AQH_MODSERVICE_ADDFOOTER_FN)(AQCGI_MODULE *m, const char *lang, GWEN_BUFFER *dbuf);
typedef struct AQH_MODSERVICE_HANDLER_ENTRY AQH_MODSERVICE_HANDLER_ENTRY; typedef struct AQH_MODSERVICE_HANDLER_ENTRY AQH_MODSERVICE_HANDLER_ENTRY;
@@ -33,52 +33,52 @@ struct AQH_MODSERVICE_HANDLER_ENTRY {
const char *page; const char *page;
int httpMethod; int httpMethod;
uint32_t perms; uint32_t perms;
void (*handlerFn)(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); void (*handlerFn)(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
}; };
void AQH_ModService_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); void AQH_ModService_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder);
AQH_SERVICE *AQH_ModService_GetService(const AQH_MODULE *m); AQCGI_SERVICE *AQH_ModService_GetService(const AQCGI_MODULE *m);
const char *AQH_ModService_GetBaseFolder(const AQH_MODULE *m); const char *AQH_ModService_GetBaseFolder(const AQCGI_MODULE *m);
uint32_t AQH_ModService_GetUserPerms(const AQH_MODULE *m); uint32_t AQH_ModService_GetUserPerms(const AQCGI_MODULE *m);
void AQH_ModService_AddHeader(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf); void AQH_ModService_AddHeader(AQCGI_MODULE *m, const char *lang, GWEN_BUFFER *dbuf);
void AQH_ModService_AddFooter(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf); void AQH_ModService_AddFooter(AQCGI_MODULE *m, const char *lang, GWEN_BUFFER *dbuf);
AQH_MODULE *AQH_ModService_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); AQCGI_MODULE *AQH_ModService_LoadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName);
int AQH_ModService_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); int AQH_ModService_HandleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem);
AQH_SESSION *AQH_ModService_ReadSession(AQH_MODULE *m, AQCGI_REQUEST *rq); AQCGI_SESSION *AQH_ModService_ReadSession(AQCGI_MODULE *m, AQCGI_REQUEST *rq);
void AQH_ModService_CalcSessionModPerms(AQH_MODULE *m, const AQH_SESSION *session); void AQH_ModService_CalcSessionModPerms(AQCGI_MODULE *m, const AQCGI_SESSION *session);
void AQH_ModService_HandleRequestWithTable(AQH_MODULE *m, void AQH_ModService_HandleRequestWithTable(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
const char *page, const char *page,
const AQH_MODSERVICE_HANDLER_ENTRY *e); const AQH_MODSERVICE_HANDLER_ENTRY *e);
int AQH_ModService_RespondWithFile(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *lang, const char *sFilename, GWEN_BUFFER *dbuf); int AQH_ModService_RespondWithFile(AQCGI_MODULE *m, AQCGI_REQUEST *rq, const char *lang, const char *sFilename, GWEN_BUFFER *dbuf);
int AQH_ModService_ReadStaticFile(AQH_MODULE *m, const char *lang, const char *filename, GWEN_BUFFER *dbuf); int AQH_ModService_ReadStaticFile(AQCGI_MODULE *m, const char *lang, const char *filename, GWEN_BUFFER *dbuf);
void AQH_ModService_AddPermDef(AQH_PERMDEF_LIST *permDefList, const char *id, uint32_t mask, const char *descr); void AQH_ModService_AddPermDef(AQCGI_PERMDEF_LIST *permDefList, const char *id, uint32_t mask, const char *descr);
void AQH_ModService_AddRole(AQH_ROLE_LIST *roleList, int id, const char *name, uint32_t perms, const char *descr); void AQH_ModService_AddRole(AQCGI_ROLE_LIST *roleList, int id, const char *name, uint32_t perms, const char *descr);
void AQH_ModService_WritePermsToForm(uint32_t perms, const AQH_PERMDEF_LIST *permDefList, const char *sPrefix, GWEN_BUFFER *dbuf); void AQH_ModService_WritePermsToForm(uint32_t perms, const AQCGI_PERMDEF_LIST *permDefList, const char *sPrefix, GWEN_BUFFER *dbuf);
uint32_t AQH_ModService_ReadPermsFromForm(GWEN_DB_NODE *dbPost, const AQH_PERMDEF_LIST *permDefList, const char *sPrefix); uint32_t AQH_ModService_ReadPermsFromForm(GWEN_DB_NODE *dbPost, const AQCGI_PERMDEF_LIST *permDefList, const char *sPrefix);
AQH_MODULE_LIST *AQH_ModService_LoadRawModules(AQH_MODULE *m); AQCGI_MODULE_LIST *AQH_ModService_LoadRawModules(AQCGI_MODULE *m);
AQH_USER_LIST *AQH_ModService_LoadRawUsers(AQH_MODULE *m); AQCGI_USER_LIST *AQH_ModService_LoadRawUsers(AQCGI_MODULE *m);
void AQH_ModService_SetHandleRequestFn(AQH_MODULE *m, AQH_MODSERVICE_HANDLEREQUEST_FN fn); void AQH_ModService_SetHandleRequestFn(AQCGI_MODULE *m, AQH_MODSERVICE_HANDLEREQUEST_FN fn);
void AQH_ModService_SetLoadSubModuleFn(AQH_MODULE *m, AQH_MODSERVICE_LOADSUBMODULE_FN fn); void AQH_ModService_SetLoadSubModuleFn(AQCGI_MODULE *m, AQH_MODSERVICE_LOADSUBMODULE_FN fn);
void AQH_ModService_SetAddHeaderFn(AQH_MODULE *m, AQH_MODSERVICE_ADDHEADER_FN fn); void AQH_ModService_SetAddHeaderFn(AQCGI_MODULE *m, AQH_MODSERVICE_ADDHEADER_FN fn);
void AQH_ModService_SetAddFooterFn(AQH_MODULE *m, AQH_MODSERVICE_ADDFOOTER_FN fn); void AQH_ModService_SetAddFooterFn(AQCGI_MODULE *m, AQH_MODSERVICE_ADDFOOTER_FN fn);
void AQH_ModService_EscapeToBuffer(const char *src, GWEN_BUFFER *buf); void AQH_ModService_EscapeToBuffer(const char *src, GWEN_BUFFER *buf);
void AQH_ModService_UnescapeToBuffer(const char *src, GWEN_BUFFER *buf); void AQH_ModService_UnescapeToBuffer(const char *src, GWEN_BUFFER *buf);
@@ -86,6 +86,16 @@ void AQH_ModService_UnescapeToBuffer(const char *src, GWEN_BUFFER *buf);
int AQH_ModService_FileIsCurrent(const char *sPath, int seconds); int AQH_ModService_FileIsCurrent(const char *sPath, int seconds);
int AQH_ModService_RespondWithMimeFile(AQCGI_REQUEST *rq, const char *sFilename, const char *sMimeType, GWEN_BUFFER *dbuf); int AQH_ModService_RespondWithMimeFile(AQCGI_REQUEST *rq, const char *sFilename, const char *sMimeType, GWEN_BUFFER *dbuf);
int AQH_ModService_RespondWithVarFile(AQCGI_MODULE *m, AQCGI_REQUEST *rq,
const char *lang,
const char *sFilename,
GWEN_DB_NODE *dbVars,
GWEN_BUFFER *dbuf);
int AQH_ModService_AddRequestUrl(const AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf);
void AQH_ModService_Redirect(AQCGI_REQUEST *rq, const char *destLocation);
void AQH_ModService_RedirectWithReferer(AQCGI_REQUEST *rq, const char *destLocation);
void AQH_ModService_DenyRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, const AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -14,7 +14,7 @@
typedef struct AQH_MOD_SERVICE AQH_MOD_SERVICE; typedef struct AQH_MOD_SERVICE AQH_MOD_SERVICE;
struct AQH_MOD_SERVICE { struct AQH_MOD_SERVICE {
AQH_SERVICE *service; AQCGI_SERVICE *service;
char *baseFolder; char *baseFolder;
uint32_t userPerms; uint32_t userPerms;

View File

@@ -13,7 +13,7 @@
#include "./musers.h" #include "./musers.h"
#include "aqhome-cgi/service/module.h" #include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
@@ -36,38 +36,37 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _createPermDefList(AQH_MODULE *m); static void _createPermDefList(AQCGI_MODULE *m);
static void _createRoleList(AQH_MODULE *m); static void _createRoleList(AQCGI_MODULE *m);
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); static AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName);
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); static int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem);
static void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqEditUserGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqEditUserGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqEditUserPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqEditUserPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqAddUserGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqAddUserGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqAddUserPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqAddUserPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static int _getHighestUserId(const AQH_USER_LIST *userList); static int _getHighestUserId(const AQCGI_USER_LIST *userList);
static int _modulePermsHasRole(const AQH_MODULE_PERMS *modPerms, uint8_t rid); static int _modulePermsHasRole(const AQCGI_MODULE_PERMS *modPerms, uint8_t rid);
static void _writeEditUserForm(AQH_MODULE *m, static void _writeEditUserForm(AQCGI_MODULE *m,
const AQH_USER *u, const AQCGI_USER *u,
const char *sAlias, const char *sAlias,
const char *sUrl, const char *sUrl,
const char *sSubmitText, const char *sSubmitText,
GWEN_BUFFER *dbuf); GWEN_BUFFER *dbuf);
static void _writeUserModRolesToForm(const AQH_ROLE_LIST *roles, const AQH_MODULE_PERMS *perms, const char *sModName, GWEN_BUFFER *dbuf); static void _writeUserModRolesToForm(const AQCGI_ROLE_LIST *roles, const AQCGI_MODULE_PERMS *perms, const char *sModName, GWEN_BUFFER *dbuf);
static void _readAllModRolesForUserFromForm(AQH_MODULE *m, GWEN_DB_NODE *dbPost, AQH_USER *u); static void _readAllModRolesForUserFromForm(AQCGI_MODULE *m, GWEN_DB_NODE *dbPost, AQCGI_USER *u);
static void _readModRolesFromForm(GWEN_DB_NODE *dbPost, static void _readModRolesFromForm(GWEN_DB_NODE *dbPost,
const AQH_ROLE_LIST *roleList, const AQCGI_ROLE_LIST *roleList,
const char *sPrefix, const char *sPrefix,
AQH_MODULE_PERMS *modPerms); AQCGI_MODULE_PERMS *modPerms);
static void _addLabelAndInputToFormTableH(const char *title, const char *name, const char *value, const char *xxtra, GWEN_BUFFER *dbuf); static void _addLabelAndInputToFormTableH(const char *title, const char *name, const char *value, const char *xxtra, GWEN_BUFFER *dbuf);
static void _addUserStateLabelAndSelectionToFormTableH(const char *sTitle, const char *sName, int st, GWEN_BUFFER *dbuf); static void _addUserStateLabelAndSelectionToFormTableH(const char *sTitle, const char *sName, int st, GWEN_BUFFER *dbuf);
static void _setLocationHeaderForMod(AQCGI_REQUEST *rq, const char *page, const char *sModName);
@@ -92,7 +91,7 @@ static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModAdmUsers_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) void AQH_ModAdmUsers_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder)
{ {
AQH_ModService_Extend(m, sv, baseFolder); AQH_ModService_Extend(m, sv, baseFolder);
AQH_ModService_SetHandleRequestFn(m, _handleRequest); AQH_ModService_SetHandleRequestFn(m, _handleRequest);
@@ -101,63 +100,63 @@ void AQH_ModAdmUsers_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFold
int AQH_ModAdmUsers_Create(AQH_SERVICE *sv) int AQH_ModAdmUsers_Create(AQCGI_SERVICE *sv)
{ {
AQH_MODULE *m; AQCGI_MODULE *m;
int rv; int rv;
m=AQH_Module_new(); m=AQCGI_Module_new();
AQH_Module_SetName(m, "users"); AQCGI_Module_SetName(m, "users");
AQH_Module_SetDescr(m, "user administration module"); AQCGI_Module_SetDescr(m, "user administration module");
AQH_Module_SetGuestPerms(m, 0); AQCGI_Module_SetGuestPerms(m, 0);
_createPermDefList(m); _createPermDefList(m);
_createRoleList(m); _createRoleList(m);
rv=AQH_Service_AddModule(sv, m); rv=AQCGI_Service_AddModule(sv, m);
if (rv<0) { if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv); DBG_INFO(NULL, "here (%d)", rv);
} }
AQH_Module_free(m); AQCGI_Module_free(m);
return rv; return rv;
} }
void _createPermDefList(AQH_MODULE *m) void _createPermDefList(AQCGI_MODULE *m)
{ {
AQH_PERMDEF_LIST *permDefList; AQCGI_PERMDEF_LIST *permDefList;
permDefList=AQH_PermDef_List_new(); permDefList=AQCGI_PermDef_List_new();
AQH_ModService_AddPermDef(permDefList, "UserRead", 0x001, "Read users"); AQH_ModService_AddPermDef(permDefList, "UserRead", 0x001, "Read users");
AQH_ModService_AddPermDef(permDefList, "UserWrite", 0x002, "Modify users"); AQH_ModService_AddPermDef(permDefList, "UserWrite", 0x002, "Modify users");
AQH_ModService_AddPermDef(permDefList, "UserAdd", 0x004, "Add users"); AQH_ModService_AddPermDef(permDefList, "UserAdd", 0x004, "Add users");
AQH_ModService_AddPermDef(permDefList, "UserDel", 0x008, "Remove users"); AQH_ModService_AddPermDef(permDefList, "UserDel", 0x008, "Remove users");
AQH_Module_SetPermDefList(m, permDefList); AQCGI_Module_SetPermDefList(m, permDefList);
} }
void _createRoleList(AQH_MODULE *m) void _createRoleList(AQCGI_MODULE *m)
{ {
AQH_ROLE_LIST *roleList; AQCGI_ROLE_LIST *roleList;
int id=0; int id=1;
roleList=AQH_Role_List_new(); roleList=AQCGI_Role_List_new();
AQH_ModService_AddRole(roleList, id++, "admin", AQH_ModService_AddRole(roleList, id++, "admin",
AQH_MODADMUSERS_PERMS_USERSREAD | AQH_MODADMUSERS_PERMS_USERSREAD |
AQH_MODADMUSERS_PERMS_USERSWRITE | AQH_MODADMUSERS_PERMS_USERSWRITE |
AQH_MODADMUSERS_PERMS_USERSADD | AQH_MODADMUSERS_PERMS_USERSADD |
AQH_MODADMUSERS_PERMS_USERSDEL, AQH_MODADMUSERS_PERMS_USERSDEL,
"Administrator Role"); "Administrator Role");
AQH_Module_SetRoleList(m, roleList); AQCGI_Module_SetRoleList(m, roleList);
} }
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName)
{ {
/* no sub-modules */ /* no sub-modules */
return NULL; return NULL;
@@ -165,7 +164,7 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem)
{ {
AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable); AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable);
return AQCGI_SendResponse(rq); return AQCGI_SendResponse(rq);
@@ -173,9 +172,9 @@ int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const
void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_USER_LIST *userList; AQCGI_USER_LIST *userList;
uint32_t perms; uint32_t perms;
perms=AQH_ModService_GetUserPerms(m); perms=AQH_ModService_GetUserPerms(m);
@@ -189,31 +188,31 @@ void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN
"</thead>\n" "</thead>\n"
"<tbody>\n"); "<tbody>\n");
if (userList) { if (userList) {
const AQH_USER *u; const AQCGI_USER *u;
AQH_User_List_SortByAlias(userList, 1); AQCGI_User_List_SortByAlias(userList, 1);
u=AQH_User_List_First(userList); u=AQCGI_User_List_First(userList);
while(u) { while(u) {
const char *sUserAlias; const char *sUserAlias;
sUserAlias=AQH_User_GetAlias(u); sUserAlias=AQCGI_User_GetAlias(u);
if (sUserAlias && *sUserAlias) { if (sUserAlias && *sUserAlias) {
uint32_t id; uint32_t id;
const char *s; const char *s;
const char *sAlias; const char *sAlias;
id=AQH_User_GetId(u); id=AQCGI_User_GetId(u);
sAlias=AQH_User_GetAlias(u); sAlias=AQCGI_User_GetAlias(u);
GBAS(dbuf, "<tr>"); GBAS(dbuf, "<tr>");
GBAA(dbuf, "<td>%lu</td>", (unsigned long int) id); GBAA(dbuf, "<td>%lu</td>", (unsigned long int) id);
GBAA(dbuf, "<td>%s</td>", sAlias?sAlias:""); GBAA(dbuf, "<td>%s</td>", sAlias?sAlias:"");
s=AQH_User_GetName(u); s=AQCGI_User_GetName(u);
GBAA(dbuf, "<td>%s</td>", s?s:""); GBAA(dbuf, "<td>%s</td>", s?s:"");
s=AQH_UserState_toString(AQH_User_GetState(u)); s=AQCGI_UserState_toString(AQCGI_User_GetState(u));
GBAA(dbuf, "<td>%s</td>", s?s:""); GBAA(dbuf, "<td>%s</td>", s?s:"");
s=AQH_User_GetEmail(u); s=AQCGI_User_GetEmail(u);
GBAA(dbuf, "<td>%s</td>", s?s:""); GBAA(dbuf, "<td>%s</td>", s?s:"");
s=AQH_User_GetNotes(u); s=AQCGI_User_GetNotes(u);
GBAA(dbuf, "<td>%s</td>", s?s:""); GBAA(dbuf, "<td>%s</td>", s?s:"");
GBAS(dbuf, "<td>"); GBAS(dbuf, "<td>");
@@ -226,12 +225,12 @@ void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN
GBAA(dbuf, "</td>\n"); GBAA(dbuf, "</td>\n");
GBAA(dbuf, "</tr>\n"); GBAA(dbuf, "</tr>\n");
} }
u=AQH_User_List_Next(u); u=AQCGI_User_List_Next(u);
} }
GBAS(dbuf, GBAS(dbuf,
"</tbody>\n" "</tbody>\n"
"</table>\n"); "</table>\n");
AQH_User_List_free(userList); AQCGI_User_List_free(userList);
} }
if (perms & AQH_MODADMUSERS_PERMS_USERSADD) if (perms & AQH_MODADMUSERS_PERMS_USERSADD)
GBAS(dbuf, "<hr><a href=\"adduser.html\">Add User</a>"); GBAS(dbuf, "<hr><a href=\"adduser.html\">Add User</a>");
@@ -239,20 +238,20 @@ void _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN
void _handleRqEditUserGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqEditUserGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sAlias; const char *sAlias;
AQH_USER *user; AQCGI_USER *user;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbQuery=AQCGI_Request_GetDbQuery(rq); dbQuery=AQCGI_Request_GetDbQuery(rq);
sAlias=dbQuery?GWEN_DB_GetCharValue(dbQuery, "alias", 0, NULL):NULL; sAlias=dbQuery?GWEN_DB_GetCharValue(dbQuery, "alias", 0, NULL):NULL;
user=(sAlias && *sAlias)?AQH_Service_LoadUser(sv, sAlias):NULL; user=(sAlias && *sAlias)?AQCGI_Service_LoadUser(sv, sAlias):NULL;
if (user) { if (user) {
_writeEditUserForm(m, user, sAlias, "edituser.html", "Save", dbuf); _writeEditUserForm(m, user, sAlias, "edituser.html", "Save", dbuf);
AQH_User_free(user); AQCGI_User_free(user);
} }
else { else {
AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html");
@@ -263,44 +262,44 @@ void _handleRqEditUserGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
void _handleRqEditUserPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqEditUserPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sAlias; const char *sAlias;
AQH_USER *u; AQCGI_USER *u;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
dbPost=AQCGI_Request_GetDbPostBody(rq); dbPost=AQCGI_Request_GetDbPostBody(rq);
sAlias=dbPost?GWEN_DB_GetCharValue(dbPost, "alias", 0, NULL):NULL; sAlias=dbPost?GWEN_DB_GetCharValue(dbPost, "alias", 0, NULL):NULL;
u=(sAlias && *sAlias)?AQH_Service_LoadUser(sv, sAlias):NULL; u=(sAlias && *sAlias)?AQCGI_Service_LoadUser(sv, sAlias):NULL;
if (u) { if (u) {
const char *s; const char *s;
int state; int state;
int rv; int rv;
s=GWEN_DB_GetCharValue(dbPost, "name", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "name", 0, NULL);
AQH_User_SetName(u, s); AQCGI_User_SetName(u, s);
s=GWEN_DB_GetCharValue(dbPost, "email", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "email", 0, NULL);
AQH_User_SetEmail(u, s); AQCGI_User_SetEmail(u, s);
s=GWEN_DB_GetCharValue(dbPost, "notes", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "notes", 0, NULL);
AQH_User_SetNotes(u, s); AQCGI_User_SetNotes(u, s);
s=GWEN_DB_GetCharValue(dbPost, "status", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "status", 0, NULL);
state=(s && *s)?AQH_UserState_fromString(s):AQH_UserState_Unknown; state=(s && *s)?AQCGI_UserState_fromString(s):AQCGI_UserState_Unknown;
if (state!=AQH_UserState_Unknown) if (state!=AQCGI_UserState_Unknown)
AQH_User_SetState(u, state); AQCGI_User_SetState(u, state);
_readAllModRolesForUserFromForm(m, dbPost, u); _readAllModRolesForUserFromForm(m, dbPost, u);
rv=AQH_Service_SaveUser(sv, u); rv=AQCGI_Service_SaveUser(sv, u);
if (rv<0) { if (rv<0) {
GBAS(dbuf, "<h2>Error</h2><p>Error saving user</p>"); GBAS(dbuf, "<h2>Error</h2><p>Error saving user</p>");
DBG_ERROR(NULL, "Could not save user \"%s\"", sAlias); DBG_ERROR(NULL, "Could not save user \"%s\"", sAlias);
AQH_User_free(u); AQCGI_User_free(u);
return; return;
} }
DBG_ERROR(NULL, "User \"%s\" saved", sAlias); DBG_ERROR(NULL, "User \"%s\" saved", sAlias);
AQH_User_free(u); AQCGI_User_free(u);
AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html");
AQCGI_Request_SetResponseCode(rq, 303); AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See other"); AQCGI_Request_SetResponseText(rq, "See other");
@@ -313,7 +312,7 @@ void _handleRqEditUserPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
void _handleRqAddUserGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqAddUserGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
DBG_ERROR(NULL, "AddUser"); DBG_ERROR(NULL, "AddUser");
_writeEditUserForm(m, NULL, NULL, "adduser.html", "Add", dbuf); _writeEditUserForm(m, NULL, NULL, "adduser.html", "Add", dbuf);
@@ -321,9 +320,9 @@ void _handleRqAddUserGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session,
void _handleRqAddUserPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqAddUserPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sAlias; const char *sAlias;
@@ -332,43 +331,41 @@ void _handleRqAddUserPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
sAlias=dbPost?GWEN_DB_GetCharValue(dbPost, "alias", 0, NULL):NULL; sAlias=dbPost?GWEN_DB_GetCharValue(dbPost, "alias", 0, NULL):NULL;
// TODO: check alias validity // TODO: check alias validity
if (sAlias) { if (sAlias) {
AQH_USER *u; AQCGI_USER *u;
const char *s; const char *s;
int state; int state;
int rv; int rv;
uint32_t userId; uint32_t userId;
AQH_USER_LIST *userList; AQCGI_USER_LIST *userList;
u=AQH_User_new(); u=AQCGI_User_new();
userList=AQH_ModService_LoadRawUsers(m); userList=AQH_ModService_LoadRawUsers(m);
userId=_getHighestUserId(userList)+1; userId=_getHighestUserId(userList)+1;
AQH_User_SetId(u, userId); AQCGI_User_SetId(u, userId);
AQH_User_SetAlias(u, sAlias); AQCGI_User_SetAlias(u, sAlias);
s=GWEN_DB_GetCharValue(dbPost, "name", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "name", 0, NULL);
AQH_User_SetName(u, s); AQCGI_User_SetName(u, s);
s=GWEN_DB_GetCharValue(dbPost, "email", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "email", 0, NULL);
AQH_User_SetEmail(u, s); AQCGI_User_SetEmail(u, s);
s=GWEN_DB_GetCharValue(dbPost, "notes", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "notes", 0, NULL);
AQH_User_SetNotes(u, s); AQCGI_User_SetNotes(u, s);
s=GWEN_DB_GetCharValue(dbPost, "status", 0, NULL); s=GWEN_DB_GetCharValue(dbPost, "status", 0, NULL);
state=(s && *s)?AQH_UserState_fromString(s):AQH_UserState_Unknown; state=(s && *s)?AQCGI_UserState_fromString(s):AQCGI_UserState_Unknown;
if (state!=AQH_UserState_Unknown) if (state!=AQCGI_UserState_Unknown)
AQH_User_SetState(u, state); AQCGI_User_SetState(u, state);
rv=AQH_Service_AddUser(sv, u); rv=AQCGI_Service_AddUser(sv, u);
if (rv<0) { if (rv<0) {
GBAS(dbuf, "<h2>Error</h2><p>Error saving user</p>"); GBAS(dbuf, "<h2>Error</h2><p>Error saving user</p>");
DBG_ERROR(NULL, "Could not save user \"%s\" (%d)", sAlias, rv); DBG_ERROR(NULL, "Could not save user \"%s\" (%d)", sAlias, rv);
AQH_User_free(u); AQCGI_User_free(u);
AQH_User_List_free(userList); AQCGI_User_List_free(userList);
return; return;
} }
DBG_ERROR(NULL, "User \"%s\" saved", sAlias); DBG_ERROR(NULL, "User \"%s\" saved", sAlias);
AQH_User_free(u); AQCGI_User_free(u);
AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); AQH_ModService_Redirect(rq, "index.html");
AQCGI_Request_SetResponseCode(rq, 303); AQCGI_User_List_free(userList);
AQCGI_Request_SetResponseText(rq, "See other");
AQH_User_List_free(userList);
} }
else { else {
DBG_ERROR(NULL, "Missing alias"); DBG_ERROR(NULL, "Missing alias");
@@ -378,20 +375,20 @@ void _handleRqAddUserPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session
int _getHighestUserId(const AQH_USER_LIST *userList) int _getHighestUserId(const AQCGI_USER_LIST *userList)
{ {
int id=0; int id=0;
if (userList) { if (userList) {
const AQH_USER *user; const AQCGI_USER *user;
user=AQH_User_List_First(userList); user=AQCGI_User_List_First(userList);
while(user) { while(user) {
int uid; int uid;
uid=AQH_User_GetId(user); uid=AQCGI_User_GetId(user);
id=(uid>id)?uid:id; id=(uid>id)?uid:id;
user=AQH_User_List_Next(user); user=AQCGI_User_List_Next(user);
} }
} }
return id; return id;
@@ -399,15 +396,15 @@ int _getHighestUserId(const AQH_USER_LIST *userList)
int _modulePermsHasRole(const AQH_MODULE_PERMS *modPerms, uint8_t rid) int _modulePermsHasRole(const AQCGI_MODULE_PERMS *modPerms, uint8_t rid)
{ {
if (modPerms) { if (modPerms) {
int arraySize; int arraySize;
int i; int i;
arraySize=AQH_ModulePerms_GetRoleArrayArraySize(); arraySize=AQCGI_ModulePerms_GetRoleArrayArraySize();
for(i=0; i<arraySize; i++) { for(i=0; i<arraySize; i++) {
if (AQH_ModulePerms_GetRoleArrayAt(modPerms, i)==rid) if (AQCGI_ModulePerms_GetRoleArrayAt(modPerms, i)==rid)
return 1; return 1;
} }
} }
@@ -419,14 +416,14 @@ int _modulePermsHasRole(const AQH_MODULE_PERMS *modPerms, uint8_t rid)
void _writeEditUserForm(AQH_MODULE *m, void _writeEditUserForm(AQCGI_MODULE *m,
const AQH_USER *u, const AQCGI_USER *u,
const char *sAlias, const char *sAlias,
const char *sUrl, const char *sUrl,
const char *sSubmitText, const char *sSubmitText,
GWEN_BUFFER *dbuf) GWEN_BUFFER *dbuf)
{ {
AQH_MODULE_LIST *moduleList; AQCGI_MODULE_LIST *moduleList;
/* write user info */ /* write user info */
GBAS(dbuf, "<h2>User Info</h2>\n"); GBAS(dbuf, "<h2>User Info</h2>\n");
@@ -435,10 +432,10 @@ void _writeEditUserForm(AQH_MODULE *m,
"<table class=\"formtable\">\n", "<table class=\"formtable\">\n",
sUrl?sUrl:""); sUrl?sUrl:"");
_addLabelAndInputToFormTableH("Alias", "alias", sAlias, "required", dbuf); _addLabelAndInputToFormTableH("Alias", "alias", sAlias, "required", dbuf);
_addLabelAndInputToFormTableH("Name", "name", u?AQH_User_GetName(u):NULL, NULL, dbuf); _addLabelAndInputToFormTableH("Name", "name", u?AQCGI_User_GetName(u):NULL, NULL, dbuf);
_addLabelAndInputToFormTableH("Email", "email", u?AQH_User_GetEmail(u):NULL, NULL, dbuf); _addLabelAndInputToFormTableH("Email", "email", u?AQCGI_User_GetEmail(u):NULL, NULL, dbuf);
_addLabelAndInputToFormTableH("Notes", "notes", u?AQH_User_GetNotes(u):NULL, NULL, dbuf); _addLabelAndInputToFormTableH("Notes", "notes", u?AQCGI_User_GetNotes(u):NULL, NULL, dbuf);
_addUserStateLabelAndSelectionToFormTableH("Status", "status", u?AQH_User_GetState(u):AQH_UserState_Unknown, dbuf); _addUserStateLabelAndSelectionToFormTableH("Status", "status", u?AQCGI_User_GetState(u):AQCGI_UserState_Unknown, dbuf);
GBAS(dbuf, "</table>\n"); GBAS(dbuf, "</table>\n");
@@ -452,26 +449,26 @@ void _writeEditUserForm(AQH_MODULE *m,
"<tbody>\n"); "<tbody>\n");
moduleList=AQH_ModService_LoadRawModules(m); moduleList=AQH_ModService_LoadRawModules(m);
if (moduleList) { if (moduleList) {
const AQH_MODULE_PERMS_LIST *modPermsList; const AQCGI_MODULE_PERMS_LIST *modPermsList;
const AQH_MODULE *currentMod; const AQCGI_MODULE *currentMod;
modPermsList=u?AQH_User_GetModulePermList(u):NULL; modPermsList=u?AQCGI_User_GetModulePermList(u):NULL;
currentMod=AQH_Module_List_First(moduleList); currentMod=AQCGI_Module_List_First(moduleList);
while(currentMod) { while(currentMod) {
const char *sModName; const char *sModName;
const AQH_MODULE_PERMS *modPerms; const AQCGI_MODULE_PERMS *modPerms;
sModName=AQH_Module_GetName(currentMod); sModName=AQCGI_Module_GetName(currentMod);
GBAA(dbuf, "<tr><td>%s</td><td>", sModName); GBAA(dbuf, "<tr><td>%s</td><td>", sModName);
modPerms=modPermsList?AQH_ModulePerms_List_GetByModuleId(modPermsList, sModName):NULL; modPerms=modPermsList?AQCGI_ModulePerms_List_GetByModuleId(modPermsList, sModName):NULL;
_writeUserModRolesToForm(AQH_Module_GetRoleList(currentMod), modPerms, sModName, dbuf); _writeUserModRolesToForm(AQCGI_Module_GetRoleList(currentMod), modPerms, sModName, dbuf);
GBAS(dbuf, "</td></tr>\n"); GBAS(dbuf, "</td></tr>\n");
GBAS(dbuf, "<td>"); GBAS(dbuf, "<td>");
currentMod=AQH_Module_List_Next(currentMod); currentMod=AQCGI_Module_List_Next(currentMod);
} /* while */ } /* while */
AQH_Module_List_free(moduleList); AQCGI_Module_List_free(moduleList);
} }
GBAS(dbuf, GBAS(dbuf,
"</tbody>\n" "</tbody>\n"
@@ -485,61 +482,61 @@ void _writeEditUserForm(AQH_MODULE *m,
void _readAllModRolesForUserFromForm(AQH_MODULE *m, GWEN_DB_NODE *dbPost, AQH_USER *u) void _readAllModRolesForUserFromForm(AQCGI_MODULE *m, GWEN_DB_NODE *dbPost, AQCGI_USER *u)
{ {
AQH_MODULE_LIST *moduleList; AQCGI_MODULE_LIST *moduleList;
moduleList=AQH_ModService_LoadRawModules(m); moduleList=AQH_ModService_LoadRawModules(m);
if (moduleList) { if (moduleList) {
AQH_MODULE_PERMS_LIST *permsList; AQCGI_MODULE_PERMS_LIST *permsList;
const AQH_MODULE *module; const AQCGI_MODULE *module;
permsList=AQH_User_GetModulePermList(u); permsList=AQCGI_User_GetModulePermList(u);
if (permsList==NULL) { if (permsList==NULL) {
DBG_ERROR(NULL, "Creating module perms list for user"); DBG_ERROR(NULL, "Creating module perms list for user");
permsList=AQH_ModulePerms_List_new(); permsList=AQCGI_ModulePerms_List_new();
AQH_User_SetModulePermList(u, permsList); AQCGI_User_SetModulePermList(u, permsList);
} }
module=AQH_Module_List_First(moduleList); module=AQCGI_Module_List_First(moduleList);
while(module) { while(module) {
const char *sModName; const char *sModName;
const AQH_ROLE_LIST *roleList; const AQCGI_ROLE_LIST *roleList;
sModName=AQH_Module_GetName(module); sModName=AQCGI_Module_GetName(module);
roleList=AQH_Module_GetRoleList(module); roleList=AQCGI_Module_GetRoleList(module);
if (sModName && *sModName && roleList) { if (sModName && *sModName && roleList) {
AQH_MODULE_PERMS *modPerms; AQCGI_MODULE_PERMS *modPerms;
modPerms=AQH_ModulePerms_List_GetByModuleId(permsList, sModName); modPerms=AQCGI_ModulePerms_List_GetByModuleId(permsList, sModName);
if (modPerms==NULL) { if (modPerms==NULL) {
modPerms=AQH_ModulePerms_new(); modPerms=AQCGI_ModulePerms_new();
AQH_ModulePerms_SetModuleId(modPerms, sModName); AQCGI_ModulePerms_SetModuleId(modPerms, sModName);
AQH_ModulePerms_List_Add(modPerms, permsList); AQCGI_ModulePerms_List_Add(modPerms, permsList);
} }
_readModRolesFromForm(dbPost, roleList, sModName, modPerms); _readModRolesFromForm(dbPost, roleList, sModName, modPerms);
} }
module=AQH_Module_List_Next(module); module=AQCGI_Module_List_Next(module);
} }
AQH_Module_List_free(moduleList); AQCGI_Module_List_free(moduleList);
} }
} }
void _writeUserModRolesToForm(const AQH_ROLE_LIST *roleList, const AQH_MODULE_PERMS *modPerms, const char *sModName, GWEN_BUFFER *dbuf) void _writeUserModRolesToForm(const AQCGI_ROLE_LIST *roleList, const AQCGI_MODULE_PERMS *modPerms, const char *sModName, GWEN_BUFFER *dbuf)
{ {
if (roleList) { if (roleList) {
const AQH_ROLE *role; const AQCGI_ROLE *role;
role=AQH_Role_List_First(roleList); role=AQCGI_Role_List_First(roleList);
while(role) { while(role) {
const char *sRoleName; const char *sRoleName;
uint8_t roleId; uint8_t roleId;
roleId=AQH_Role_GetId(role); roleId=AQCGI_Role_GetId(role);
sRoleName=AQH_Role_GetName(role); sRoleName=AQCGI_Role_GetName(role);
if (sRoleName && *sRoleName) { if (sRoleName && *sRoleName) {
int isChecked; int isChecked;
@@ -553,7 +550,7 @@ void _writeUserModRolesToForm(const AQH_ROLE_LIST *roleList, const AQH_MODULE_PE
GBAA(dbuf, "<label for=\"%s\">%s</label>", sRoleName, sRoleName); GBAA(dbuf, "<label for=\"%s\">%s</label>", sRoleName, sRoleName);
} }
} }
role=AQH_Role_List_Next(role); role=AQCGI_Role_List_Next(role);
} }
} }
} }
@@ -561,15 +558,15 @@ void _writeUserModRolesToForm(const AQH_ROLE_LIST *roleList, const AQH_MODULE_PE
void _readModRolesFromForm(GWEN_DB_NODE *dbPost, void _readModRolesFromForm(GWEN_DB_NODE *dbPost,
const AQH_ROLE_LIST *roleList, const AQCGI_ROLE_LIST *roleList,
const char *sPrefix, const char *sPrefix,
AQH_MODULE_PERMS *modPerms) AQCGI_MODULE_PERMS *modPerms)
{ {
AQH_ModulePerms_PresetRoleArray(modPerms, 0); AQCGI_ModulePerms_PresetRoleArray(modPerms, 0);
if (roleList) { if (roleList) {
GWEN_BUFFER *tbuf; GWEN_BUFFER *tbuf;
uint32_t pos; uint32_t pos;
const AQH_ROLE *role; const AQCGI_ROLE *role;
int nextRolePos=0; int nextRolePos=0;
tbuf=GWEN_Buffer_new(0, 256, 0, 1); tbuf=GWEN_Buffer_new(0, 256, 0, 1);
@@ -577,24 +574,27 @@ void _readModRolesFromForm(GWEN_DB_NODE *dbPost,
GBAA(tbuf, "%s:", sPrefix); GBAA(tbuf, "%s:", sPrefix);
pos=GWEN_Buffer_GetPos(tbuf); pos=GWEN_Buffer_GetPos(tbuf);
role=AQH_Role_List_First(roleList); role=AQCGI_Role_List_First(roleList);
while(role) { while(role) {
const char *roleName; const char *roleName;
roleName=AQH_Role_GetName(role); roleName=AQCGI_Role_GetName(role);
if (roleName && *roleName) { if (roleName && *roleName) {
const char *s; const char *s;
GBAS(tbuf, roleName); GBAS(tbuf, roleName);
s=GWEN_DB_GetCharValue(dbPost, GWEN_Buffer_GetStart(tbuf), 0, NULL); s=GWEN_DB_GetCharValue(dbPost, GWEN_Buffer_GetStart(tbuf), 0, NULL);
/*DBG_ERROR(NULL, "Role string %s = [%s]", GWEN_Buffer_GetStart(tbuf), s?s:"<empty>");*/
if (s && *s) { if (s && *s) {
if (nextRolePos<AQH_ModulePerms_GetRoleArrayArraySize()) if (nextRolePos<AQCGI_ModulePerms_GetRoleArrayArraySize()) {
AQH_ModulePerms_SetRoleArrayAt(modPerms, nextRolePos++, AQH_Role_GetId(role)); /*DBG_ERROR(NULL, "Setting role \"%s\" (%d)", roleName, AQCGI_Role_GetId(role));*/
AQCGI_ModulePerms_SetRoleArrayAt(modPerms, nextRolePos++, AQCGI_Role_GetId(role));
}
} }
GWEN_Buffer_Crop(tbuf, 0, pos); GWEN_Buffer_Crop(tbuf, 0, pos);
} }
role=AQH_Role_List_Next(role); role=AQCGI_Role_List_Next(role);
} /* while */ } /* while */
GWEN_Buffer_free(tbuf); GWEN_Buffer_free(tbuf);
} }
@@ -612,10 +612,10 @@ void _addUserStateLabelAndSelectionToFormTableH(const char *sTitle, const char *
GBAA(dbuf, "<tr><td><label for=\"%s\">%s:</label></td>", sName?sName:"", sTitle?sTitle:""); GBAA(dbuf, "<tr><td><label for=\"%s\">%s:</label></td>", sName?sName:"", sTitle?sTitle:"");
GBAA(dbuf, "<td><select name=\"%s\">", sName?sName:""); GBAA(dbuf, "<td><select name=\"%s\">", sName?sName:"");
for(i=AQH_UserState_Unknown; i<=AQH_UserState_Active; i++) { for(i=AQCGI_UserState_Unknown; i<=AQCGI_UserState_Active; i++) {
const char *s; const char *s;
s=AQH_UserState_toString(i); s=AQCGI_UserState_toString(i);
GBAA(dbuf, "<option value=\"%s\" %s>%s</option>", s, (i==st)?"selected":"", s); GBAA(dbuf, "<option value=\"%s\" %s>%s</option>", s, (i==st)?"selected":"", s);
} }
GBAS(dbuf, "</select></td></tr>"); GBAS(dbuf, "</select></td></tr>");

View File

@@ -24,9 +24,9 @@
void AQH_ModAdmUsers_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); void AQH_ModAdmUsers_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder);
int AQH_ModAdmUsers_Create(AQH_SERVICE *sv); int AQH_ModAdmUsers_Create(AQCGI_SERVICE *sv);

View File

@@ -22,9 +22,10 @@
#include "aqhome-cgi/modules/devices/mdevices_device.h" #include "aqhome-cgi/modules/devices/mdevices_device.h"
#include "aqhome-cgi/modules/devices/mdevices_setdevice.h" #include "aqhome-cgi/modules/devices/mdevices_setdevice.h"
#include "aqhome-cgi/modules/devices/mdevices_page.h" #include "aqhome-cgi/modules/devices/mdevices_page.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -51,20 +52,20 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); static AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName);
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); static int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem);
static void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqIndexGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqValuesTableGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqValuesTableGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqValuesGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqValuesGraphGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqValueGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqSetDataPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqGraphGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqDeviceGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqDeviceGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqDevicePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqDevicePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqPageGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqPageGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqPagePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqPagePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static void _handleRqPageGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqPageGraphGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf);
static AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues); static AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues);
@@ -100,7 +101,7 @@ static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) void AQH_ModDevices_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder)
{ {
AQH_ModService_Extend(m, sv, baseFolder); AQH_ModService_Extend(m, sv, baseFolder);
AQH_ModService_SetHandleRequestFn(m, _handleRequest); AQH_ModService_SetHandleRequestFn(m, _handleRequest);
@@ -109,14 +110,14 @@ void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolde
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName)
{ {
return NULL; return NULL;
} }
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem)
{ {
AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable); AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable);
return AQCGI_SendResponse(rq); return AQCGI_SendResponse(rq);
@@ -124,77 +125,77 @@ int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const
void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqIndexGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunIndex, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunIndex, dbuf);
} }
void _handleRqValuesTableGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqValuesTableGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsTable, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsTable, dbuf);
} }
void _handleRqValuesGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqValuesGraphGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsGraph, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsGraph, dbuf);
} }
void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqValueGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValue, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValue, dbuf);
} }
void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqSetDataPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetData, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetData, dbuf);
} }
void _handleRqGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqGraphGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunGraphValue, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunGraphValue, dbuf);
} }
void _handleRqDeviceGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqDeviceGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunDevice, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunDevice, dbuf);
} }
void _handleRqDevicePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqDevicePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetDevice, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetDevice, dbuf);
} }
void _handleRqPageGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqPageGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPageGet, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPageGet, dbuf);
} }
void _handleRqPagePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqPagePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPagePost, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPagePost, dbuf);
} }
void _handleRqPageGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) void _handleRqPageGraphGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, GWEN_BUFFER *dbuf)
{ {
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPageGraph, dbuf); AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPageGraph, dbuf);
} }
@@ -538,6 +539,25 @@ AQDG_GRAPH_DATAPAIR_LIST *AQH_ModDevices_RequestDataPairList(AQH_DATACLIENT *dc,
void AQH_ModDevices_RedirectToDevice(AQCGI_REQUEST *rq, const char *destLocation, const AQH_DEVICE *device)
{
const char *sDeviceName;
GWEN_BUFFER *pbuf;
sDeviceName=AQH_Device_GetName(device);
pbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendString(pbuf, "Location: ");
GWEN_Buffer_AppendString(pbuf, (destLocation && *destLocation)?destLocation:"index.html");
if (sDeviceName && *sDeviceName) {
GWEN_Buffer_AppendString(pbuf, "?device=");
GWEN_Text_EscapeToBuffer(sDeviceName, pbuf);
}
AQH_ModService_Redirect(rq, GWEN_Buffer_GetStart(pbuf));
GWEN_Buffer_free(pbuf);
}
AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues) AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues)
{ {
AQDG_GRAPH_DATAPAIR_LIST *dpList; AQDG_GRAPH_DATAPAIR_LIST *dpList;

View File

@@ -39,8 +39,8 @@
void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); void AQH_ModDevices_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder);
int AQH_ModDevices_Create(AQH_SERVICE *sv); int AQH_ModDevices_Create(AQCGI_SERVICE *sv);
uint32_t AQH_ModDevices_ColorFromHexString(const char *s); uint32_t AQH_ModDevices_ColorFromHexString(const char *s);
@@ -64,6 +64,7 @@ uint32_t AQH_ModDevices_ValueGetLastDataAsUint32(AQH_DATACLIENT *dc, const AQH_V
AQDG_GRAPH_DATAPAIR_LIST *AQH_ModDevices_RequestDataPairList(AQH_DATACLIENT *dc, const char *systemValueName, AQDG_GRAPH_DATAPAIR_LIST *AQH_ModDevices_RequestDataPairList(AQH_DATACLIENT *dc, const char *systemValueName,
uint64_t tsBegin, uint64_t tsEnd, uint64_t num); uint64_t tsBegin, uint64_t tsEnd, uint64_t num);
void AQH_ModDevices_RedirectToDevice(AQCGI_REQUEST *rq, const char *destLocation, const AQH_DEVICE *device);

View File

@@ -13,9 +13,10 @@
#include "./mdevices_device.h" #include "./mdevices_device.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -38,9 +39,9 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _runDeviceWithArgs(AQH_MODULE *m, static void _runDeviceWithArgs(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
AQH_DATACLIENT *dc, AQH_DATACLIENT *dc,
const char *sDeviceName, const char *sDeviceName,
GWEN_BUFFER *dbuf); GWEN_BUFFER *dbuf);
@@ -54,7 +55,7 @@ static void _addFieldToForm(const char *sFieldTitle, const char *sFieldName, con
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunDevice(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sDeviceName; const char *sDeviceName;
@@ -74,9 +75,9 @@ void AQH_ModDevices_RunDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *ses
void _runDeviceWithArgs(AQH_MODULE *m, void _runDeviceWithArgs(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
AQH_DATACLIENT *dc, AQH_DATACLIENT *dc,
const char *sDeviceName, const char *sDeviceName,
GWEN_BUFFER *dbuf) GWEN_BUFFER *dbuf)

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunDevice(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -13,9 +13,10 @@
#include "./mdevices_index.h" #include "./mdevices_index.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -45,7 +46,7 @@ static void _addLinkForDevice(const char *page, const char *sDevice, const char
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
AQH_DEVICE_LIST *deviceList; AQH_DEVICE_LIST *deviceList;
AQH_DEVICE *device; AQH_DEVICE *device;

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -13,9 +13,10 @@
#include "./mdevices_init.h" #include "./mdevices_init.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -40,8 +41,8 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _createPermDefList(AQH_MODULE *m); static void _createPermDefList(AQCGI_MODULE *m);
static void _createRoleList(AQH_MODULE *m); static void _createRoleList(AQCGI_MODULE *m);
@@ -50,34 +51,34 @@ static void _createRoleList(AQH_MODULE *m);
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
int AQH_ModDevices_Create(AQH_SERVICE *sv) int AQH_ModDevices_Create(AQCGI_SERVICE *sv)
{ {
AQH_MODULE *m; AQCGI_MODULE *m;
int rv; int rv;
m=AQH_Module_new(); m=AQCGI_Module_new();
AQH_Module_SetName(m, "devices"); AQCGI_Module_SetName(m, "devices");
AQH_Module_SetDescr(m, "device module"); AQCGI_Module_SetDescr(m, "device module");
AQH_Module_SetGuestPerms(m, 0); AQCGI_Module_SetGuestPerms(m, 0);
_createPermDefList(m); _createPermDefList(m);
_createRoleList(m); _createRoleList(m);
rv=AQH_Service_AddModule(sv, m); rv=AQCGI_Service_AddModule(sv, m);
if (rv<0) { if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv); DBG_INFO(NULL, "here (%d)", rv);
} }
AQH_Module_free(m); AQCGI_Module_free(m);
return rv; return rv;
} }
void _createPermDefList(AQH_MODULE *m) void _createPermDefList(AQCGI_MODULE *m)
{ {
AQH_PERMDEF_LIST *permDefList; AQCGI_PERMDEF_LIST *permDefList;
permDefList=AQH_PermDef_List_new(); permDefList=AQCGI_PermDef_List_new();
AQH_ModService_AddPermDef(permDefList, "DeviceRead", 0x001, "Read and list devices"); AQH_ModService_AddPermDef(permDefList, "DeviceRead", 0x001, "Read and list devices");
AQH_ModService_AddPermDef(permDefList, "DeviceWrite", 0x002, "Modify devices"); AQH_ModService_AddPermDef(permDefList, "DeviceWrite", 0x002, "Modify devices");
@@ -90,17 +91,17 @@ void _createPermDefList(AQH_MODULE *m)
AQH_ModService_AddPermDef(permDefList, "ValueDel", 0x080, "Remove values"); AQH_ModService_AddPermDef(permDefList, "ValueDel", 0x080, "Remove values");
AQH_ModService_AddPermDef(permDefList, "ValueSet", 0x100, "Set values"); AQH_ModService_AddPermDef(permDefList, "ValueSet", 0x100, "Set values");
AQH_Module_SetPermDefList(m, permDefList); AQCGI_Module_SetPermDefList(m, permDefList);
} }
void _createRoleList(AQH_MODULE *m) void _createRoleList(AQCGI_MODULE *m)
{ {
AQH_ROLE_LIST *roleList; AQCGI_ROLE_LIST *roleList;
int id=0; int id=1;
roleList=AQH_Role_List_new(); roleList=AQCGI_Role_List_new();
AQH_ModService_AddRole(roleList, id++, "Reader", AQH_ModService_AddRole(roleList, id++, "Reader",
AQH_MODDEVICES_PERMS_DEVICEREAD | AQH_MODDEVICES_PERMS_DEVICEREAD |
AQH_MODDEVICES_PERMS_VALUEREAD, AQH_MODDEVICES_PERMS_VALUEREAD,
@@ -121,7 +122,7 @@ void _createRoleList(AQH_MODULE *m)
AQH_MODDEVICES_PERMS_VALUEREAD | AQH_MODDEVICES_PERMS_VALUEREAD |
AQH_MODDEVICES_PERMS_VALUESET, AQH_MODDEVICES_PERMS_VALUESET,
"Set values"); "Set values");
AQH_Module_SetRoleList(m, roleList); AQCGI_Module_SetRoleList(m, roleList);
} }

View File

@@ -21,7 +21,7 @@
int AQH_ModDevices_Create(AQH_SERVICE *sv); int AQH_ModDevices_Create(AQCGI_SERVICE *sv);
#endif #endif

View File

@@ -13,9 +13,10 @@
#include "./mdevices_page.h" #include "./mdevices_page.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <aqdiagram/graph/timegraph.h> #include <aqdiagram/graph/timegraph.h>
#include <aqdiagram/graph/w_graph.h> #include <aqdiagram/graph/w_graph.h>
#include <aqdiagram/draw/context_cairo.h> #include <aqdiagram/draw/context_cairo.h>
@@ -54,19 +55,19 @@ enum {
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _writePage(AQH_MODULE *m, AQH_DATACLIENT *dc, GWEN_XMLNODE *nPage, GWEN_BUFFER *dbuf); static void _writePage(AQCGI_MODULE *m, AQH_DATACLIENT *dc, GWEN_XMLNODE *nPage, GWEN_BUFFER *dbuf);
static void _writeItem(AQH_MODULE *m, AQH_DATACLIENT *dc, const char *sPageId, GWEN_XMLNODE *nItem, GWEN_BUFFER *dbuf); static void _writeItem(AQCGI_MODULE *m, AQH_DATACLIENT *dc, const char *sPageId, GWEN_XMLNODE *nItem, GWEN_BUFFER *dbuf);
static void _writeActor(AQH_DATACLIENT *dc, const char *sPageId, GWEN_XMLNODE *n, int layout, GWEN_BUFFER *dbuf); static void _writeActor(AQH_DATACLIENT *dc, const char *sPageId, GWEN_XMLNODE *n, int layout, GWEN_BUFFER *dbuf);
static void _writeGraph(const char *sPageId, GWEN_XMLNODE *n, int layout, GWEN_BUFFER *dbuf); static void _writeGraph(const char *sPageId, GWEN_XMLNODE *n, int layout, GWEN_BUFFER *dbuf);
static void _handlePageActor(AQCGI_REQUEST *rq, AQH_DATACLIENT *dc, const char *sActorId, GWEN_XMLNODE *nActor); static void _handlePageActor(AQCGI_REQUEST *rq, AQH_DATACLIENT *dc, const char *sActorId, GWEN_XMLNODE *nActor);
static void _handlePageGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_DATACLIENT *dc, const char *sGraphId, GWEN_XMLNODE *nGraph, GWEN_BUFFER *dbuf); static void _handlePageGraph(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQH_DATACLIENT *dc, const char *sGraphId, GWEN_XMLNODE *nGraph, GWEN_BUFFER *dbuf);
static void _genPageGraph(AQH_DATACLIENT *dc, const char *sGraphId, const char *sFilename, GWEN_XMLNODE *nGraph); static void _genPageGraph(AQH_DATACLIENT *dc, const char *sGraphId, const char *sFilename, GWEN_XMLNODE *nGraph);
static void _addCurves(AQH_DATACLIENT *dc, AQDG_GRAPH *g, GWEN_XMLNODE *nGraph, uint64_t tsBegin, uint64_t tsEnd); static void _addCurves(AQH_DATACLIENT *dc, AQDG_GRAPH *g, GWEN_XMLNODE *nGraph, uint64_t tsBegin, uint64_t tsEnd);
static AQDG_GRAPH_DATAPAIR_LIST *_readCurveData(AQH_DATACLIENT *dc, GWEN_XMLNODE *nCurve, uint64_t tsBegin, uint64_t tsEnd); static AQDG_GRAPH_DATAPAIR_LIST *_readCurveData(AQH_DATACLIENT *dc, GWEN_XMLNODE *nCurve, uint64_t tsBegin, uint64_t tsEnd);
static uint64_t _parseTime(const char *s); static uint64_t _parseTime(const char *s);
static GWEN_XMLNODE *_getSubItemNode(GWEN_XMLNODE *nPage, const char *sId, const char *sElementName); static GWEN_XMLNODE *_getSubItemNode(GWEN_XMLNODE *nPage, const char *sId, const char *sElementName);
static void _mkPathForGraph(AQH_MODULE *m, const char *sGraphId, GWEN_BUFFER *dbuf); static void _mkPathForGraph(AQCGI_MODULE *m, const char *sGraphId, GWEN_BUFFER *dbuf);
static void _addGraphLink(const char *sPageId, const char *sGraphId, int w, int h, GWEN_BUFFER *dbuf); static void _addGraphLink(const char *sPageId, const char *sGraphId, int w, int h, GWEN_BUFFER *dbuf);
static void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf); static void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf);
static void _writeOnOffToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf); static void _writeOnOffToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf);
@@ -76,9 +77,9 @@ static int _getColorComponent(GWEN_DB_NODE *dbPost, const char *sValueName, cons
static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _sendPageList(AQH_MODULE *m, GWEN_BUFFER *dbuf); static void _sendPageList(AQCGI_MODULE *m, GWEN_BUFFER *dbuf);
static GWEN_STRINGLIST *_listPageFiles(AQH_MODULE *m); static GWEN_STRINGLIST *_listPageFiles(AQCGI_MODULE *m);
static GWEN_XMLNODE *_readPage(AQH_MODULE *m, const char *sPageName); static GWEN_XMLNODE *_readPage(AQCGI_MODULE *m, const char *sPageName);
static GWEN_XMLNODE *_readPageFile(const char *sFilename); static GWEN_XMLNODE *_readPageFile(const char *sFilename);
static int _layoutFromString(const char *s); static int _layoutFromString(const char *s);
@@ -89,7 +90,7 @@ static int _layoutFromString(const char *s);
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunPageGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunPageGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sPageId; const char *sPageId;
@@ -126,7 +127,7 @@ void AQH_ModDevices_RunPageGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *se
void AQH_ModDevices_RunPageGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunPageGraph(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sPageId; const char *sPageId;
@@ -161,7 +162,7 @@ void AQH_ModDevices_RunPageGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *
void AQH_ModDevices_RunPagePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunPagePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sPageId; const char *sPageId;
@@ -246,7 +247,7 @@ void _handlePageActor(AQCGI_REQUEST *rq, AQH_DATACLIENT *dc, const char *sActorI
void _handlePageGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_DATACLIENT *dc, const char *sGraphId, GWEN_XMLNODE *nGraph, GWEN_BUFFER *dbuf) void _handlePageGraph(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQH_DATACLIENT *dc, const char *sGraphId, GWEN_XMLNODE *nGraph, GWEN_BUFFER *dbuf)
{ {
GWEN_BUFFER *fbuf; GWEN_BUFFER *fbuf;
int refreshTime; int refreshTime;
@@ -459,13 +460,13 @@ GWEN_XMLNODE *_getSubItemNode(GWEN_XMLNODE *nPage, const char *sId, const char *
void _mkPathForGraph(AQH_MODULE *m, const char *sGraphId, GWEN_BUFFER *buf) void _mkPathForGraph(AQCGI_MODULE *m, const char *sGraphId, GWEN_BUFFER *buf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
const char *s; const char *s;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
s=AQH_Service_GetCacheFolder(sv); s=AQCGI_Service_GetCacheFolder(sv);
GBAA(buf, "%s%s%s", s, GWEN_DIR_SEPARATOR_S, sGraphId); GBAA(buf, "%s%s%s", s, GWEN_DIR_SEPARATOR_S, sGraphId);
AQH_ModService_EscapeToBuffer(s, buf); AQH_ModService_EscapeToBuffer(s, buf);
GBAS(buf, ".png"); GBAS(buf, ".png");
@@ -473,7 +474,7 @@ void _mkPathForGraph(AQH_MODULE *m, const char *sGraphId, GWEN_BUFFER *buf)
void _writePage(AQH_MODULE *m, AQH_DATACLIENT *dc, GWEN_XMLNODE *nPage, GWEN_BUFFER *dbuf) void _writePage(AQCGI_MODULE *m, AQH_DATACLIENT *dc, GWEN_XMLNODE *nPage, GWEN_BUFFER *dbuf)
{ {
const char *sPageId; const char *sPageId;
GWEN_XMLNODE *nItem; GWEN_XMLNODE *nItem;
@@ -515,7 +516,7 @@ void _writePage(AQH_MODULE *m, AQH_DATACLIENT *dc, GWEN_XMLNODE *nPage, GWEN_BUF
void _writeItem(AQH_MODULE *m, AQH_DATACLIENT *dc, const char *sPageId, GWEN_XMLNODE *nItem, GWEN_BUFFER *dbuf) void _writeItem(AQCGI_MODULE *m, AQH_DATACLIENT *dc, const char *sPageId, GWEN_XMLNODE *nItem, GWEN_BUFFER *dbuf)
{ {
GWEN_XMLNODE *n; GWEN_XMLNODE *n;
uint32_t perms; uint32_t perms;
@@ -819,7 +820,7 @@ void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *s
void _sendPageList(AQH_MODULE *m, GWEN_BUFFER *dbuf) void _sendPageList(AQCGI_MODULE *m, GWEN_BUFFER *dbuf)
{ {
GWEN_STRINGLIST *sl; GWEN_STRINGLIST *sl;
@@ -870,16 +871,16 @@ void _sendPageList(AQH_MODULE *m, GWEN_BUFFER *dbuf)
GWEN_STRINGLIST *_listPageFiles(AQH_MODULE *m) GWEN_STRINGLIST *_listPageFiles(AQCGI_MODULE *m)
{ {
GWEN_BUFFER *fbuf; GWEN_BUFFER *fbuf;
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_STRINGLIST *sl; GWEN_STRINGLIST *sl;
int rv; int rv;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
fbuf=GWEN_Buffer_new(0, 256, 0, 1); fbuf=GWEN_Buffer_new(0, 256, 0, 1);
GBAA(fbuf, "%s%spages", AQH_Service_GetRuntimeFolder(sv), GWEN_DIR_SEPARATOR_S); GBAA(fbuf, "%s%spages", AQCGI_Service_GetRuntimeFolder(sv), GWEN_DIR_SEPARATOR_S);
sl=GWEN_StringList_new(); sl=GWEN_StringList_new();
rv=GWEN_Directory_GetMatchingFilesRecursively(GWEN_Buffer_GetStart(fbuf), sl, "*.xml"); rv=GWEN_Directory_GetMatchingFilesRecursively(GWEN_Buffer_GetStart(fbuf), sl, "*.xml");
if (rv<0) { if (rv<0) {
@@ -900,15 +901,15 @@ GWEN_STRINGLIST *_listPageFiles(AQH_MODULE *m)
GWEN_XMLNODE *_readPage(AQH_MODULE *m, const char *sPageName) GWEN_XMLNODE *_readPage(AQCGI_MODULE *m, const char *sPageName)
{ {
GWEN_BUFFER *fbuf; GWEN_BUFFER *fbuf;
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_XMLNODE *fileNode; GWEN_XMLNODE *fileNode;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
fbuf=GWEN_Buffer_new(0, 256, 0, 1); fbuf=GWEN_Buffer_new(0, 256, 0, 1);
GBAA(fbuf, "%s%spages%s", AQH_Service_GetRuntimeFolder(sv), GWEN_DIR_SEPARATOR_S, GWEN_DIR_SEPARATOR_S); GBAA(fbuf, "%s%spages%s", AQCGI_Service_GetRuntimeFolder(sv), GWEN_DIR_SEPARATOR_S, GWEN_DIR_SEPARATOR_S);
AQH_ModService_EscapeToBuffer(sPageName, fbuf); AQH_ModService_EscapeToBuffer(sPageName, fbuf);
GBAS(fbuf, ".xml"); GBAS(fbuf, ".xml");

View File

@@ -21,9 +21,9 @@
void AQH_ModDevices_RunPageGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunPageGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
void AQH_ModDevices_RunPagePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunPagePost(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
void AQH_ModDevices_RunPageGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunPageGraph(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -13,9 +13,10 @@
#include "./mdevices_setdata.h" #include "./mdevices_setdata.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -36,6 +37,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _setIntData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); static void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
@@ -47,9 +49,9 @@ static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunSetData(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sDeviceName; const char *sDeviceName;
const char *sValueName; const char *sValueName;
@@ -75,8 +77,7 @@ void AQH_ModDevices_RunSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *se
case AQH_ValueModality_RGBW: _setRgbwData(dc, value, sValue); break; case AQH_ValueModality_RGBW: _setRgbwData(dc, value, sValue); break;
case AQH_ValueModality_OnOff: _setOnOffData(dc, value, sValue); break; case AQH_ValueModality_OnOff: _setOnOffData(dc, value, sValue); break;
case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sValue); break; case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sValue); break;
default: default: _setIntData(dc, value, sValue); break;
break;
} /* switch */ } /* switch */
} /* if (sValueName) */ } /* if (sValueName) */
} }
@@ -104,6 +105,29 @@ void AQH_ModDevices_RunSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *se
void _setIntData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
{
if (sValue) {
const char *sValueSystemName;
int intVal;
int rv;
sValueSystemName=AQH_Value_GetNameForSystem(value);
if (1==sscanf(sValue, "%d", &intVal)) {
DBG_ERROR(NULL, "Send value [%d] to %s", intVal, sValueSystemName);
rv=AQH_DataClient_SetData(dc, value, (double) intVal);
if (rv<0) {
DBG_ERROR(NULL, "Error sending data: %d", rv);
}
}
else {
DBG_ERROR(NULL, "Not an integer value: [%s]", sValue);
}
}
}
void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue) void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
{ {
if (sValue) { if (sValue) {

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunSetData(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -13,9 +13,10 @@
#include "./mdevices_setdevice.h" #include "./mdevices_setdevice.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -45,9 +46,9 @@ static void _handleDeviceForm(AQH_DATACLIENT *dc, AQH_DEVICE *device, GWEN_DB_NO
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunSetDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunSetDevice(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
const char *sDeviceName; const char *sDeviceName;
AQH_DEVICE *device; AQH_DEVICE *device;
@@ -76,17 +77,7 @@ void AQH_ModDevices_RunSetDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *
DBG_ERROR(NULL, "device not found"); DBG_ERROR(NULL, "device not found");
} }
if (sDeviceName && *sDeviceName) { AQH_ModDevices_RedirectToDevice(rq, "device.html", device);
GWEN_BUFFER *pbuf;
pbuf=GWEN_Buffer_new(0, 256, 0, 1);
GBAS(pbuf, "Location: device.html?device=");
GWEN_Text_EscapeToBuffer(sDeviceName, pbuf);
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(pbuf));
GWEN_Buffer_free(pbuf);
}
AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See other");
} }

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunSetDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunSetDevice(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -13,9 +13,10 @@
#include "./mdevices_value.h" #include "./mdevices_value.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -36,13 +37,14 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _runValueWithArgs(AQH_MODULE *m, static void _runValueWithArgs(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
AQH_DATACLIENT *dc, AQH_DATACLIENT *dc,
const char *sDeviceName, const char *sDeviceName,
const char *sValueName, const char *sValueName,
GWEN_BUFFER *dbuf); GWEN_BUFFER *dbuf);
static void _writeIntToForm(const char *sValueName, int v, GWEN_BUFFER *dbuf);
static void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf); static void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
static void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf); static void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf);
static void _writeOnOffToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf); static void _writeOnOffToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf);
@@ -55,7 +57,7 @@ static void _writeOnOffAutoToForm(const char *sValueName, int intVal, GWEN_BUFFE
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunValue(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sDeviceName; const char *sDeviceName;
@@ -100,9 +102,9 @@ void AQH_ModDevices_RunValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sess
void _runValueWithArgs(AQH_MODULE *m, void _runValueWithArgs(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
AQH_DATACLIENT *dc, AQH_DATACLIENT *dc,
const char *sDeviceName, const char *sDeviceName,
const char *sValueName, const char *sValueName,
@@ -198,7 +200,7 @@ void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *
case AQH_ValueModality_RGBW: _writeRgbwToForm(sValueName, u.f, dbuf); break; case AQH_ValueModality_RGBW: _writeRgbwToForm(sValueName, u.f, dbuf); break;
case AQH_ValueModality_OnOff: _writeOnOffToForm(sValueName, intVal, dbuf); break; case AQH_ValueModality_OnOff: _writeOnOffToForm(sValueName, intVal, dbuf); break;
case AQH_ValueModality_OnOffAuto: _writeOnOffAutoToForm(sValueName, intVal, dbuf); break; case AQH_ValueModality_OnOffAuto: _writeOnOffAutoToForm(sValueName, intVal, dbuf); break;
default: GBAA(dbuf, "%.2f", u.f); break; default: _writeIntToForm(sValueName, intVal, dbuf); break;
} /* switch */ } /* switch */
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>"); GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
@@ -207,6 +209,13 @@ void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *
void _writeIntToForm(const char *sValueName, int v, GWEN_BUFFER *dbuf)
{
GBAA(dbuf, "<input type=\"number\" name=\"%s\" value=\"%d\"/>", sValueName, v);
}
void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf) void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf)
{ {
#if 1 #if 1

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunValue(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -14,9 +14,10 @@
#include "./mdevices_valuesgraph.h" #include "./mdevices_valuesgraph.h"
#include "./mdevices_index.h" #include "./mdevices_index.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -41,6 +42,7 @@ static void _writeValueToDetailedTable(const char *sDeviceName, const AQH_VALUE
static void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf); static void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf);
static void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf); static void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
static void _addGraphLink(const char *sDeviceName, const char *sValueName, const char *sPeriod, GWEN_BUFFER *dbuf, int withLink); static void _addGraphLink(const char *sDeviceName, const char *sValueName, const char *sPeriod, GWEN_BUFFER *dbuf, int withLink);
static void _writeDeviceInfo(const AQH_DEVICE *device, GWEN_BUFFER *dbuf);
@@ -49,7 +51,7 @@ static void _addGraphLink(const char *sDeviceName, const char *sValueName, const
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunValuesAsGraph(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sDeviceName; const char *sDeviceName;
@@ -59,6 +61,10 @@ void AQH_ModDevices_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSI
if (!(sDeviceName && *sDeviceName)) if (!(sDeviceName && *sDeviceName))
AQH_ModDevices_RunIndex(m, rq, session, dc, dbuf); AQH_ModDevices_RunIndex(m, rq, session, dc, dbuf);
else { else {
AQH_DEVICE *device;
device=AQH_DataClient_GetDeviceByName(dc, sDeviceName);
if (device) {
const char *sValueName; const char *sValueName;
sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL); sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL);
@@ -66,6 +72,7 @@ void AQH_ModDevices_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSI
AQH_VALUE *value; AQH_VALUE *value;
GBAA(dbuf,"<h1>Value %s/%s</h1>\n", sDeviceName, sValueName); GBAA(dbuf,"<h1>Value %s/%s</h1>\n", sDeviceName, sValueName);
_writeDeviceInfo(device, dbuf);
value=AQH_ModDevices_GetValueForDevice(dc, sDeviceName, sValueName); value=AQH_ModDevices_GetValueForDevice(dc, sDeviceName, sValueName);
if (value) { if (value) {
_writeValueToDetailedTable(sDeviceName, value, dbuf); _writeValueToDetailedTable(sDeviceName, value, dbuf);
@@ -80,6 +87,7 @@ void AQH_ModDevices_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSI
if (valueList && AQH_Value_List_GetCount(valueList)) { if (valueList && AQH_Value_List_GetCount(valueList)) {
GBAA(dbuf,"<h1>Values for Device %s</h1>\n", sDeviceName); GBAA(dbuf,"<h1>Values for Device %s</h1>\n", sDeviceName);
_writeDeviceInfo(device, dbuf);
_writeValueListToTable(sDeviceName, valueList, dbuf); _writeValueListToTable(sDeviceName, valueList, dbuf);
GBAS(dbuf, "\n"); GBAS(dbuf, "\n");
} }
@@ -89,7 +97,31 @@ void AQH_ModDevices_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSI
AQH_Value_List_free(valueList); AQH_Value_List_free(valueList);
AQCGI_Request_AddResponseHeaderData(rq, "Refresh: 305"); AQCGI_Request_AddResponseHeaderData(rq, "Refresh: 305");
} }
AQH_Device_free(device);
} }
}
}
void _writeDeviceInfo(const AQH_DEVICE *device, GWEN_BUFFER *dbuf)
{
const char *s;
int cnt=0;
GBAS(dbuf, "<p>");
s=AQH_Device_GetNameForGui(device);
if (s)
GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
s=AQH_Device_GetRoomName(device);
if (s)
GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
s=AQH_Device_GetLocation(device);
if (s)
GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
s=AQH_Device_GetDescription(device);
if (s)
GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
GBAS(dbuf, "</p>");
} }

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunValuesAsGraph(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -14,9 +14,10 @@
#include "./mdevices_valuestable.h" #include "./mdevices_valuestable.h"
#include "./mdevices_index.h" #include "./mdevices_index.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h> #include <gwenhywfar/text.h>
@@ -47,7 +48,7 @@ static void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value,
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunValuesAsTable(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunValuesAsTable(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sDeviceName; const char *sDeviceName;

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunValuesAsTable(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunValuesAsTable(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -13,9 +13,10 @@
#include "./mdevices_vgraph.h" #include "./mdevices_vgraph.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/mdataclient.h" #include "aqhome-cgi/modules/mdataclient.h"
#include <aqcgi/service/module.h>
#include <aqdiagram/graph/timegraph.h> #include <aqdiagram/graph/timegraph.h>
#include <aqdiagram/graph/w_graph.h> #include <aqdiagram/graph/w_graph.h>
#include <aqdiagram/draw/context_cairo.h> #include <aqdiagram/draw/context_cairo.h>
@@ -54,7 +55,7 @@ struct MY_GRAPH_PARAMS {
static MY_GRAPH_PARAMS _graphParams[]={ static MY_GRAPH_PARAMS _graphParamsAny[]={
{"4h", "last 4 hours", "Lm5", 4*60*60, 2*60}, {"4h", "last 4 hours", "Lm5", 4*60*60, 2*60},
{"1d", "last 24 hours", "Lm30", 24*60*60, 5*60}, {"1d", "last 24 hours", "Lm30", 24*60*60, 5*60},
{"1w", "last 7 days", "Lm240", 7*24*60*60, 15*60}, {"1w", "last 7 days", "Lm240", 7*24*60*60, 15*60},
@@ -66,12 +67,24 @@ static MY_GRAPH_PARAMS _graphParams[]={
static MY_GRAPH_PARAMS _graphParamsBool[]={
{"4h", "last 4 hours", "Sa5", 4*60*60, 2*60},
{"1d", "last 24 hours", "Sa30", 24*60*60, 5*60},
{"1w", "last 7 days", "Sa240", 7*24*60*60, 15*60},
{"1m", "last 30 days", "Sa480", 30*24*60*60, 60*60},
{"6m", "last 6 months", "Sa720", 182*24*60*60, 60*60},
{"12m","last 12 months", "Sa1440", 365*24*60*60, 60*60},
{NULL, NULL, NULL, 0, 0}
};
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* forward declarations * forward declarations
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static void _runGraphValueWithArgs(AQH_MODULE *m, static void _runGraphValueWithArgs(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_DATACLIENT *dc, AQH_DATACLIENT *dc,
const char *sDeviceName, const char *sDeviceName,
@@ -83,8 +96,8 @@ static void _createGraph(AQH_DATACLIENT *dc,
const char *graphTitle, int precision, const char *curveLabel, const char *graphTitle, int precision, const char *curveLabel,
const char *sImgFile, int imgWidth, int imgHeight, uint64_t numDataPoints); const char *sImgFile, int imgWidth, int imgHeight, uint64_t numDataPoints);
static AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, const MY_GRAPH_PARAMS *graphParams, int precision); static AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, const MY_GRAPH_PARAMS *graphParams, int precision);
static void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, GWEN_BUFFER *dbuf); static void _mkPathForValueAndPeriod(AQCGI_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, GWEN_BUFFER *dbuf);
static const MY_GRAPH_PARAMS *_getParamsByName(const char *s); static const MY_GRAPH_PARAMS *_getParamsByName(const char *s, int modality);
@@ -93,7 +106,7 @@ static const MY_GRAPH_PARAMS *_getParamsByName(const char *s);
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDevices_RunGraphValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) void AQH_ModDevices_RunGraphValue(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{ {
GWEN_DB_NODE *dbQuery; GWEN_DB_NODE *dbQuery;
const char *sDeviceName; const char *sDeviceName;
@@ -123,7 +136,7 @@ void AQH_ModDevices_RunGraphValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION
void _runGraphValueWithArgs(AQH_MODULE *m, void _runGraphValueWithArgs(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_DATACLIENT *dc, AQH_DATACLIENT *dc,
const char *sDeviceName, const char *sDeviceName,
@@ -138,9 +151,6 @@ void _runGraphValueWithArgs(AQH_MODULE *m,
DBG_DEBUG(NULL, "GraphValue with args"); DBG_DEBUG(NULL, "GraphValue with args");
dbQuery=AQCGI_Request_GetDbQuery(rq); dbQuery=AQCGI_Request_GetDbQuery(rq);
sPeriod=GWEN_DB_GetCharValue(dbQuery, "period", 0, NULL); sPeriod=GWEN_DB_GetCharValue(dbQuery, "period", 0, NULL);
graphParams=_getParamsByName(sPeriod);
if (graphParams==NULL)
graphParams=&_graphParams[0];
DBG_DEBUG(NULL, "Device=%s, value=%s, period=%s", DBG_DEBUG(NULL, "Device=%s, value=%s, period=%s",
sDeviceName?sDeviceName:"<empty>", sValueName?sValueName:"<empty>", sDeviceName?sDeviceName:"<empty>", sValueName?sValueName:"<empty>",
sPeriod?sPeriod:"<empty>"); sPeriod?sPeriod:"<empty>");
@@ -149,6 +159,7 @@ void _runGraphValueWithArgs(AQH_MODULE *m,
if (value) { if (value) {
GWEN_BUFFER *fbuf; GWEN_BUFFER *fbuf;
graphParams=_getParamsByName(sPeriod, AQH_Value_GetModality(value));
fbuf=GWEN_Buffer_new(0, 256, 0, 1); fbuf=GWEN_Buffer_new(0, 256, 0, 1);
_mkPathForValueAndPeriod(m, value, graphParams, fbuf); _mkPathForValueAndPeriod(m, value, graphParams, fbuf);
if (!AQH_ModService_FileIsCurrent(GWEN_Buffer_GetStart(fbuf), graphParams->acceptedAgeInSeconds)) { if (!AQH_ModService_FileIsCurrent(GWEN_Buffer_GetStart(fbuf), graphParams->acceptedAgeInSeconds)) {
@@ -241,15 +252,15 @@ AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, const MY_GRAPH_PARAM
} }
void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, GWEN_BUFFER *dbuf) void _mkPathForValueAndPeriod(AQCGI_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
const char *s; const char *s;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
/* cache folder */ /* cache folder */
s=AQH_Service_GetCacheFolder(sv); s=AQCGI_Service_GetCacheFolder(sv);
GBAA(dbuf, "%s%s", s, GWEN_DIR_SEPARATOR_S); GBAA(dbuf, "%s%s", s, GWEN_DIR_SEPARATOR_S);
/* var name */ /* var name */
@@ -261,18 +272,26 @@ void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_
const MY_GRAPH_PARAMS *_getParamsByName(const char *s) const MY_GRAPH_PARAMS *_getParamsByName(const char *s, int modality)
{ {
const MY_GRAPH_PARAMS *startP;
const MY_GRAPH_PARAMS *p; const MY_GRAPH_PARAMS *p;
p=_graphParams; switch(modality) {
case AQH_ValueModality_Door:
case AQH_ValueModality_Motion:
case AQH_ValueModality_OnOff: startP=_graphParamsBool; break;
default: startP=_graphParamsAny; break;
}
p=startP;
while(p->name) { while(p->name) {
if (strcasecmp(p->name, s)==0) if (strcasecmp(p->name, s)==0)
return p; return p;
p++; p++;
} }
return NULL; return startP;
} }

View File

@@ -21,7 +21,7 @@
void AQH_ModDevices_RunGraphValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); void AQH_ModDevices_RunGraphValue(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
#endif #endif

View File

@@ -0,0 +1,12 @@
<?xml?>
<gwbuild>
<data dist="true" install="$(httpdatadir)/aqhome-cgi/html">
style.css
</data>
<subdirs>
pics
</subdirs>
</gwbuild>

View File

@@ -0,0 +1,17 @@
<?xml?>
<gwbuild>
<data dist="true" install="$(httpdatadir)/aqhome-cgi/html/pics">
cancel.png
document-table.png
edit.png
graph.png
minus.png
ok.png
plus.png
user-add.png
user-edit.png
</data>
</gwbuild>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -13,11 +13,11 @@
#include "./mdataclient.h" #include "./mdataclient.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome/msg/ipc/m_ipc.h" #include "aqhome/msg/ipc/m_ipc.h"
#include "aqhome/msg/ipc/data/m_ipcd.h" #include "aqhome/msg/ipc/data/m_ipcd.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
@@ -43,7 +43,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
void AQH_ModDataClient_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) void AQH_ModDataClient_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder)
{ {
AQH_ModService_Extend(m, sv, baseFolder); AQH_ModService_Extend(m, sv, baseFolder);
@@ -51,9 +51,9 @@ void AQH_ModDataClient_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFo
void AQH_ModDataClient_HandleRequest(AQH_MODULE *m, void AQH_ModDataClient_HandleRequest(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
AQH_MODDATACLIENT_RUN_FN runFn, AQH_MODDATACLIENT_RUN_FN runFn,
GWEN_BUFFER *dbuf) GWEN_BUFFER *dbuf)
{ {

View File

@@ -20,13 +20,13 @@
typedef void (*AQH_MODDATACLIENT_RUN_FN)(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); typedef void (*AQH_MODDATACLIENT_RUN_FN)(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
void AQH_ModDataClient_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); void AQH_ModDataClient_Extend(AQCGI_MODULE *m, AQCGI_SERVICE *sv, const char *baseFolder);
void AQH_ModDataClient_HandleRequest(AQH_MODULE *m, void AQH_ModDataClient_HandleRequest(AQCGI_MODULE *m,
AQCGI_REQUEST *rq, AQCGI_REQUEST *rq,
AQH_SESSION *session, AQCGI_SESSION *session,
AQH_MODDATACLIENT_RUN_FN runFn, AQH_MODDATACLIENT_RUN_FN runFn,
GWEN_BUFFER *dbuf); GWEN_BUFFER *dbuf);

View File

@@ -13,12 +13,14 @@
#include "./mroot_p.h" #include "./mroot_p.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/modules/devices/mdevices.h" #include "aqhome-cgi/modules/devices/mdevices.h"
#include "aqhome-cgi/modules/common/madmin.h" #include "aqhome-cgi/modules/common/madmin.h"
#include <aqcgi/service/module.h>
#include <gwenhywfar/debug.h> #include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h> #include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h>
@@ -27,6 +29,10 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
#define AQH_SERVICE_SESSION_MAXAGE 86400
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* global vars * global vars
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
@@ -37,12 +43,13 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); static AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sModuleName);
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); static int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, const char *sLastPathElem);
static int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf); static int _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf);
static int _handleRqLogin(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf); static int _handleRqLogin(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf);
static int _handleRqLoginPost(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf); static int _handleRqLoginGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf);
static AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf); static int _handleRqLoginPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq);
static AQCGI_USER *_getAndCheckUser(AQCGI_MODULE *m, AQCGI_REQUEST *rq);
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -50,11 +57,11 @@ static AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
AQH_MODULE *AQH_ModRoot_new(AQH_SERVICE *sv, const char *baseFolder) AQCGI_MODULE *AQH_ModRoot_new(AQCGI_SERVICE *sv, const char *baseFolder)
{ {
AQH_MODULE *m; AQCGI_MODULE *m;
m=AQH_Module_new(); m=AQCGI_Module_new();
AQH_ModService_Extend(m, sv, baseFolder); AQH_ModService_Extend(m, sv, baseFolder);
AQH_ModService_SetHandleRequestFn(m, _handleRequest); AQH_ModService_SetHandleRequestFn(m, _handleRequest);
AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule); AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule);
@@ -64,15 +71,15 @@ AQH_MODULE *AQH_ModRoot_new(AQH_SERVICE *sv, const char *baseFolder)
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) AQCGI_MODULE *_loadSubModule(AQCGI_MODULE *m, GWEN_UNUSED AQCGI_REQUEST *rq, GWEN_UNUSED AQCGI_SESSION *session, const char *sModuleName)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
if (strcasecmp(sModuleName, "devices")==0) { if (strcasecmp(sModuleName, "devices")==0) {
AQH_MODULE *mSub; AQCGI_MODULE *mSub;
mSub=AQH_Service_LoadModule(sv, sModuleName); mSub=AQCGI_Service_LoadModule(sv, sModuleName);
if (mSub) { if (mSub) {
const char *s; const char *s;
GWEN_BUFFER *nbuf; GWEN_BUFFER *nbuf;
@@ -82,25 +89,25 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
GWEN_Buffer_AppendArgs(nbuf, "%s/devices", s?s:"."); GWEN_Buffer_AppendArgs(nbuf, "%s/devices", s?s:".");
AQH_ModDevices_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf)); AQH_ModDevices_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf));
AQH_Module_Tree2_AddChild(m, mSub); AQCGI_Module_Tree2_AddChild(m, mSub);
GWEN_Buffer_free(nbuf); GWEN_Buffer_free(nbuf);
return mSub; return mSub;
} }
} }
else if (strcasecmp(sModuleName, "admin")==0) { else if (strcasecmp(sModuleName, "admin")==0) {
AQH_MODULE *mSub; AQCGI_MODULE *mSub;
mSub=AQH_Service_LoadModule(sv, sModuleName); mSub=AQCGI_Service_LoadModule(sv, sModuleName);
if (mSub) { if (mSub) {
const char *s; const char *s;
GWEN_BUFFER *nbuf; GWEN_BUFFER *nbuf;
nbuf=GWEN_Buffer_new(0, 256, 0, 1); nbuf=GWEN_Buffer_new(0, 256, 0, 1);
s=AQH_ModService_GetBaseFolder(m); s=AQH_ModService_GetBaseFolder(m);
GWEN_Buffer_AppendArgs(nbuf, "%s/devices", s?s:"."); GWEN_Buffer_AppendArgs(nbuf, "%s/admin", s?s:".");
AQH_ModAdmin_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf)); AQH_ModAdmin_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf));
AQH_Module_Tree2_AddChild(m, mSub); AQCGI_Module_Tree2_AddChild(m, mSub);
GWEN_Buffer_free(nbuf); GWEN_Buffer_free(nbuf);
return mSub; return mSub;
} }
@@ -110,7 +117,7 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) int _handleRequest(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_UNUSED AQCGI_SESSION *session, const char *sLastPathElem)
{ {
GWEN_BUFFER *dbuf; GWEN_BUFFER *dbuf;
@@ -143,7 +150,7 @@ int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const
int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf) int _handleRqIndex(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
{ {
if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET)
return AQH_ModService_RespondWithFile(m, rq, "en", "index.html", dbuf); return AQH_ModService_RespondWithFile(m, rq, "en", "index.html", dbuf);
@@ -157,12 +164,12 @@ int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
int _handleRqLogin(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf) int _handleRqLogin(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
{ {
if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET)
AQH_ModService_RespondWithFile(m, rq, "en", "login.html", dbuf); _handleRqLoginGet(m, rq, dbuf);
else if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_POST) else if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_POST)
_handleRqLoginPost(m, rq, dbuf); _handleRqLoginPost(m, rq);
else { else {
DBG_ERROR(NULL, "Invalid request method %d", AQCGI_Request_GetRequestMethod(rq)); DBG_ERROR(NULL, "Invalid request method %d", AQCGI_Request_GetRequestMethod(rq));
AQCGI_Request_SetResponseCode(rq, 405); AQCGI_Request_SetResponseCode(rq, 405);
@@ -174,85 +181,127 @@ int _handleRqLogin(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
int _handleRqLoginPost(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf) int _handleRqLoginGet(AQCGI_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
{ {
AQH_SERVICE *sv; GWEN_DB_NODE *dbQuery;
AQH_USER *user; const char *sSrc;
AQH_SESSION *session; GWEN_DB_NODE *dbVars;
int rv;
dbVars=GWEN_DB_Group_new("vars");
dbQuery=AQCGI_Request_GetDbQuery(rq);
sSrc=dbQuery?GWEN_DB_GetCharValue(dbQuery, "src", 0, NULL):NULL;
if (sSrc && *sSrc)
GWEN_DB_SetCharValue(dbVars, 0, "destination", sSrc);
rv=AQH_ModService_RespondWithVarFile(m, rq, "en", "login.html", dbVars, dbuf);
GWEN_DB_Group_free(dbVars);
return rv;
}
int _handleRqLoginPost(AQCGI_MODULE *m, AQCGI_REQUEST *rq)
{
AQCGI_SERVICE *sv;
AQCGI_USER *user;
AQCGI_SESSION *session;
GWEN_BUFFER *tbuf; GWEN_BUFFER *tbuf;
GWEN_TIMESTAMP *ts; GWEN_TIMESTAMP *ts;
GWEN_DB_NODE *dbPost;
const char *s;
int rv; int rv;
DBG_ERROR(NULL, "Handling request"); DBG_ERROR(NULL, "Handling request");
sv=AQH_ModService_GetService(m); sv=AQH_ModService_GetService(m);
user=_getAndCheckUser(m, rq, dbuf); user=_getAndCheckUser(m, rq);
if (user==NULL) { if (user==NULL) {
DBG_INFO(NULL, "here"); DBG_INFO(NULL, "here");
AQCGI_Request_SetResponseCode(rq, 500);
AQCGI_Request_SetResponseText(rq, "Internal Error");
return GWEN_ERROR_GENERIC; return GWEN_ERROR_GENERIC;
} }
ts=GWEN_Timestamp_NowInLocalTime(); ts=GWEN_Timestamp_NowInLocalTime();
AQH_User_SetTimestampLastLogin(user, ts); AQCGI_User_SetTimestampLastLogin(user, ts);
DBG_ERROR(NULL, "Saving user"); rv=AQCGI_Service_SaveUser(sv, user);
rv=AQH_Service_SaveUser(sv, user);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "Error saving user \"%s\"", AQH_User_GetAlias(user)); DBG_ERROR(NULL, "Error saving user \"%s\"", AQCGI_User_GetAlias(user));
AQCGI_Request_SetResponseCode(rq, 500); AQCGI_Request_SetResponseCode(rq, 500);
AQCGI_Request_SetResponseText(rq, "Internal Error"); AQCGI_Request_SetResponseText(rq, "Internal Error");
AQH_User_free(user); AQCGI_User_free(user);
return rv; return rv;
} }
/* generate session */ /* generate session */
DBG_ERROR(NULL, "Generating session");
tbuf=GWEN_Buffer_new(0, 64, 0, 1); tbuf=GWEN_Buffer_new(0, 64, 0, 1);
AQCGI_GenerateSessionId(tbuf); AQCGI_GenerateSessionId(tbuf);
session=AQH_Session_new(); session=AQCGI_Session_new();
AQH_Session_SetTimestampCreation(session, ts); AQCGI_Session_SetTimestampCreation(session, ts);
AQH_Session_SetTimestampLastAccess(session, ts); AQCGI_Session_SetTimestampLastAccess(session, ts);
AQH_Session_SetUid(session, GWEN_Buffer_GetStart(tbuf)); AQCGI_Session_SetUid(session, GWEN_Buffer_GetStart(tbuf));
GWEN_Buffer_free(tbuf); GWEN_Buffer_free(tbuf);
AQH_Session_SetUserAlias(session, AQH_User_GetAlias(user)); AQCGI_Session_SetUserAlias(session, AQCGI_User_GetAlias(user));
rv=AQH_Service_AddSession(sv, session); rv=AQCGI_Service_AddSession(sv, session);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "Error adding session for user \"%s\" (%d)", AQH_User_GetAlias(user), rv); DBG_ERROR(NULL, "Error adding session for user \"%s\" (%d)", AQCGI_User_GetAlias(user), rv);
AQCGI_Request_SetResponseCode(rq, 500); AQCGI_Request_SetResponseCode(rq, 500);
AQCGI_Request_SetResponseText(rq, "Internal Error"); AQCGI_Request_SetResponseText(rq, "Internal Error");
AQH_Session_free(session); AQCGI_Session_free(session);
AQH_User_free(user); AQCGI_User_free(user);
return GWEN_ERROR_INTERNAL; return GWEN_ERROR_INTERNAL;
} }
/* add Set-Cookie header */ /* add Set-Cookie header */
tbuf=GWEN_Buffer_new(0, 256, 0, 1); tbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(tbuf, "Set-Cookie: session=%s; max-age=86400", AQH_Session_GetUid(session)); GWEN_Buffer_AppendArgs(tbuf, "Set-Cookie: session=%s; max-age=%d", AQCGI_Session_GetUid(session), AQH_SERVICE_SESSION_MAXAGE);
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(tbuf)); AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(tbuf));
GWEN_Buffer_free(tbuf); GWEN_Buffer_free(tbuf);
/* finish */ /* finish */
dbPost=AQCGI_Request_GetDbPostBody(rq);
s=dbPost?GWEN_DB_GetCharValue(dbPost, "dest", 0, NULL):NULL;
if (s && *s) {
GWEN_BUFFER *ubuf;
ubuf=GWEN_Buffer_new(0, 128, 0, 1);
if (GWEN_Text_UnescapeToBufferTolerant(s, ubuf)>=0) {
const char *p;
p=GWEN_Buffer_GetStart(ubuf);
if (*p=='/')
AQH_ModService_Redirect(rq, p);
else {
DBG_ERROR(NULL, "Destination does not start with \"/\", not using it [%s]", p);
AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html");
AQCGI_Request_SetResponseCode(rq, 303); AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See other"); AQCGI_Request_SetResponseText(rq, "See other");
AQH_Session_free(session); }
AQH_User_free(user); }
GWEN_Buffer_free(ubuf);
}
else {
AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html");
AQCGI_Request_SetResponseCode(rq, 303);
AQCGI_Request_SetResponseText(rq, "See other");
}
AQCGI_Session_free(session);
AQCGI_User_free(user);
return 0; return 0;
} }
AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf) AQCGI_USER *_getAndCheckUser(AQCGI_MODULE *m, AQCGI_REQUEST *rq)
{ {
GWEN_DB_NODE *dbPost; GWEN_DB_NODE *dbPost;
dbPost=AQCGI_Request_GetDbPostBody(rq); dbPost=AQCGI_Request_GetDbPostBody(rq);
if (dbPost) { if (dbPost) {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
const char *sUserName; const char *sUserName;
const char *sPasswd; const char *sPasswd;
AQH_USER *user; AQCGI_USER *user;
const char *hashedPaswd; const char *hashedPaswd;
GWEN_BUFFER *buf; GWEN_BUFFER *buf;
@@ -267,7 +316,7 @@ AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
} }
DBG_ERROR(NULL, "Loading user \"%s\" (%p)", sUserName, sv); DBG_ERROR(NULL, "Loading user \"%s\" (%p)", sUserName, sv);
user=AQH_Service_LoadUser(sv, sUserName); user=AQCGI_Service_LoadUser(sv, sUserName);
if (user==NULL) { if (user==NULL) {
DBG_ERROR(NULL, "User \"%s\" not found", sUserName); DBG_ERROR(NULL, "User \"%s\" not found", sUserName);
AQCGI_Request_SetResponseCode(rq, 403); AQCGI_Request_SetResponseCode(rq, 403);
@@ -276,20 +325,20 @@ AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
} }
DBG_ERROR(NULL, "Loaded user \"%s\"", sUserName); DBG_ERROR(NULL, "Loaded user \"%s\"", sUserName);
if (AQH_User_GetState(user)!=AQH_UserState_Active) { if (AQCGI_User_GetState(user)!=AQCGI_UserState_Active) {
DBG_ERROR(NULL, "User \"%s\" not active", sUserName); DBG_ERROR(NULL, "User \"%s\" not active", sUserName);
AQCGI_Request_SetResponseCode(rq, 403); AQCGI_Request_SetResponseCode(rq, 403);
AQCGI_Request_SetResponseText(rq, "Forbidden"); AQCGI_Request_SetResponseText(rq, "Forbidden");
AQH_User_free(user); AQCGI_User_free(user);
return NULL; return NULL;
} }
hashedPaswd=AQH_User_GetHashedPassword(user); hashedPaswd=AQCGI_User_GetHashedPassword(user);
if (!(hashedPaswd && *hashedPaswd)) { if (!(hashedPaswd && *hashedPaswd)) {
DBG_ERROR(NULL, "User \"%s\" has no hashed password", sUserName); DBG_ERROR(NULL, "User \"%s\" has no hashed password", sUserName);
AQCGI_Request_SetResponseCode(rq, 403); AQCGI_Request_SetResponseCode(rq, 403);
AQCGI_Request_SetResponseText(rq, "Forbidden"); AQCGI_Request_SetResponseText(rq, "Forbidden");
AQH_User_free(user); AQCGI_User_free(user);
return NULL; return NULL;
} }
buf=GWEN_Buffer_new(0, 256, 0, 1); buf=GWEN_Buffer_new(0, 256, 0, 1);
@@ -301,7 +350,7 @@ AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq, GWEN_BUFFER *dbuf)
AQCGI_Request_SetResponseCode(rq, 403); AQCGI_Request_SetResponseCode(rq, 403);
AQCGI_Request_SetResponseText(rq, "Forbidden"); AQCGI_Request_SetResponseText(rq, "Forbidden");
GWEN_Buffer_free(buf); GWEN_Buffer_free(buf);
AQH_User_free(user); AQCGI_User_free(user);
return NULL; return NULL;
} }
GWEN_Buffer_free(buf); GWEN_Buffer_free(buf);

View File

@@ -16,10 +16,8 @@
#include <gwenhywfar/buffer.h> #include <gwenhywfar/buffer.h>
AQH_MODULE *AQH_ModRoot_new(AQH_SERVICE *sv, const char *baseFolder); AQCGI_MODULE *AQH_ModRoot_new(AQCGI_SERVICE *sv, const char *baseFolder);
AQH_MODULE *AQH_ModRoot_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sModuleName);
int AQH_ModRoot_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sLastPathElem);

View File

@@ -4,6 +4,7 @@
<h3>Enter your login credentials</h3> <h3>Enter your login credentials</h3>
<form action="login" method="post"> <form action="login" method="post">
<input type="hidden" name="dest" value="$(destination)">
<label for="userid">Username:</label> <label for="userid">Username:</label>
<input type="text" id="userid" name="userid" placeholder="Enter your Username" required> <input type="text" id="userid" name="userid" placeholder="Enter your Username" required>
<label for="password">Password:</label> <label for="password">Password:</label>
@@ -20,6 +21,4 @@
</a> </a>
</p> </p>
</div> </div>
</body>
</html>

View File

@@ -1,63 +0,0 @@
body {
background-color: whitesmoke;
}
table.datatable {
border: thin solid;
border-collapse: collapse;
}
table.datatable th, td {
border: thin solid;
border-collapse: collapse;
padding: 5px;
}
table.datatable tbody tr:nth-child(odd) {
background-color: #ffffff;
}
table.formtable {
border: thin solid;
border-collapse: collapse;
}
table.formtable th, td {
border: thin solid;
border-collapse: collapse;
padding: 5px;
}
ul.mainmenu {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333333;
}
ul.mainmenu li {
float: left;
}
ul.mainmenu li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
ul.mainmenu li a:hover {
background-color: #111111;
}

View File

@@ -1,86 +0,0 @@
<?xml?>
<gwbuild>
<target type="ConvenienceLibrary" name="aqhcgi_service" >
<includes type="c" >
$(gwenhywfar_cflags)
-I$(topsrcdir)
-I$(topbuilddir)
-I$(topsrcdir)/apps
-I$(topbuilddir)/apps
-I$(builddir)
-I$(srcdir)
</includes>
<includes type="tm2" >
--include=$(builddir)
--include=$(srcdir)
</includes>
<define name="not_BUILDING_AQHOME" />
<setVar name="local/cflags">$(visibility_cflags)</setVar>
<setVar name="tm2flags-INACTIVE" >
--api=AQHOME_API
</setVar>
<setVar name="local/typefiles" >
module.t2d
moduleperms.t2d
role.t2d
user.t2d
session.t2d
permdef.t2d
</setVar>
<setVar name="local/built_sources" >
</setVar>
<setVar name="local/built_headers_pub">
</setVar>
<setVar name="local/built_headers_priv" >
</setVar>
<headers dist="false" install="$(pkgincludedir)/service" >
$(local/built_headers_pub)
</headers>
<headers dist="true" install="$(pkgincludedir)/service" >
service.h
</headers>
<headers dist="true" >
service_p.h
</headers>
<sources>
$(local/typefiles)
service.c
</sources>
<extradist>
</extradist>
<useTargets>
</useTargets>
<subdirs>
</subdirs>
</target>
</gwbuild>

View File

@@ -1,20 +0,0 @@
- service:
- userList
- rootModule
- sessionList
- user:
- modulePerms
- module:
- roleList
- permDefList
- session

View File

@@ -1,103 +0,0 @@
<?xml?>
<tm2>
<type id="AQH_MODULE" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQH_MODULE</identifier>
<prefix>AQH_Module</prefix>
<baseFileName>module</baseFileName>
<flags>
with_inherit
with_xml
with_db
with_list1
with_list2
with_tree2
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="post">aqhome-cgi/service/role.h</header>
<header type="sys" loc="post">aqhome-cgi/service/permdef.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQH_MODULE_FLAGS" prefix="AQH_MODULE_FLAGS_">
<item name="ACTIVE" value="0x00000001" />
</define>
</defines>
<members>
<member name="id" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember sortbymember</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember sortbymember</flags>
</member>
<member name="descr" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="guestPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="roleList" type="AQH_ROLE_LIST" elementName="role" >
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
<getflags>none</getflags>
<setflags>none</setflags>
</member>
<member name="permDefList" type="AQH_PERMDEF_LIST" elementName="permdef" >
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
<getflags>none</getflags>
<setflags>none</setflags>
</member>
</members>
</type>
</tm2>

View File

@@ -1,67 +0,0 @@
<?xml?>
<tm2>
<type id="AQH_MODULE_PERMS" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQH_MODULE_PERMS</identifier>
<prefix>AQH_ModulePerms</prefix>
<baseFileName>moduleperms</baseFileName>
<flags>
with_inherit
with_xml
with_db
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="post">aqhome-cgi/service/role.h</header>
</headers>
<inlines>
</inlines>
</lang>
<members>
<member name="moduleId" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember sortbymember</flags>
</member>
<member name="explAddPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="explDelPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="roleArray" type="uint8_t_array" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
</members>
</type>
</tm2>

View File

@@ -1,65 +0,0 @@
<?xml?>
<tm2>
<type id="AQH_PERMDEF" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQH_PERMDEF</identifier>
<prefix>AQH_PermDef</prefix>
<baseFileName>permdef</baseFileName>
<flags>
with_xml
with_db
with_list1
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
</headers>
<inlines>
</inlines>
</lang>
<members>
<member name="id" type="char_ptr" maxlen="32">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="32">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="mask" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="descr" type="char_ptr" maxlen="256">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
</members>
</type>
</tm2>

View File

@@ -1,79 +0,0 @@
<?xml?>
<tm2>
<type id="AQH_ROLE" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQH_ROLE</identifier>
<prefix>AQH_Role</prefix>
<baseFileName>role</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
</headers>
<inlines>
</inlines>
</lang>
<members>
<member name="id" type="uint8_t" maxlen="1">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="descr" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="perms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="explAddPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="explDelPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
</members>
</type>
</tm2>

View File

@@ -1,414 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
//#define DISABLE_DEBUGLOG
#include "aqhome-cgi/service/service_p.h"
#include <gwenhywfar/stringlist.h>
#include <gwenhywfar/text.h>
#include <gwenhywfar/debug.h>
GWEN_INHERIT_FUNCTIONS(AQH_SERVICE);
GWEN_LIST_FUNCTIONS(AQH_SERVICE, AQH_Service);
AQH_SERVICE *AQH_Service_new(const char *baseFolder, const char *baseUrl)
{
AQH_SERVICE *sv;
GWEN_NEW_OBJECT(AQH_SERVICE, sv);
GWEN_INHERIT_INIT(AQH_SERVICE, sv);
GWEN_LIST_INIT(AQH_SERVICE, sv);
sv->baseUrl=baseUrl?strdup(baseUrl):NULL;
sv->baseFolder=baseFolder?strdup(baseFolder):NULL;
if (sv->baseFolder) {
GWEN_BUFFER *dbuf;
uint32_t pos;
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(dbuf, "%s%s", sv->baseFolder, GWEN_DIR_SEPARATOR_S);
pos=GWEN_Buffer_GetPos(dbuf);
/* data folder */
GWEN_Buffer_AppendString(dbuf, "data");
sv->runtimeFolder=strdup(GWEN_Buffer_GetStart(dbuf));
DBG_ERROR(NULL, "Runtime folder: %s", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_Crop(dbuf, 0, pos);
/* cache folder */
GWEN_Buffer_AppendString(dbuf, "cache");
sv->cacheFolder=strdup(GWEN_Buffer_GetStart(dbuf));
DBG_ERROR(NULL, "Cache folder: %s", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_Crop(dbuf, 0, pos);
GWEN_Buffer_free(dbuf);
}
return sv;
}
void AQH_Service_free(AQH_SERVICE *sv)
{
if (sv) {
GWEN_LIST_FINI(AQH_SERVICE, sv);
GWEN_INHERIT_FINI(AQH_SERVICE, sv);
free(sv->baseUrl);
free(sv->baseFolder);
free(sv->runtimeFolder);
free(sv->cacheFolder);
GWEN_FREE_OBJECT(sv);
}
}
const char *AQH_Service_GetBaseUrl(const AQH_SERVICE *sv)
{
return sv?sv->baseUrl:NULL;
}
const char *AQH_Service_GetBaseFolder(const AQH_SERVICE *sv)
{
return sv?sv->baseFolder:NULL;
}
const char *AQH_Service_GetRuntimeFolder(const AQH_SERVICE *sv)
{
return sv?sv->runtimeFolder:NULL;
}
const char *AQH_Service_GetCacheFolder(const AQH_SERVICE *sv)
{
return sv?sv->cacheFolder:NULL;
}
#if 0
AQH_MODULE *AQH_Service_GetModuleByPath(const AQH_SERVICE *sv, const char *s)
{
if (sv && s && *s) {
GWEN_STRINGLIST *sl;
sl=GWEN_StringList_fromString2(s, "/", 0,
GWEN_TEXT_FLAGS_DEL_QUOTES |
GWEN_TEXT_FLAGS_DEL_LEADING_BLANKS |
GWEN_TEXT_FLAGS_DEL_MULTIPLE_BLANKS |
GWEN_TEXT_FLAGS_DEL_TRAILING_BLANKS);
if (sl) {
GWEN_STRINGLISTENTRY *se;
AQH_MODULE *m;
m=sv->rootModule;
se=GWEN_StringList_FirstEntry(sl);
while(se && m) {
const char *sWantedName;
sWantedName=GWEN_StringListEntry_Data(se);
if (sWantedName && *sWantedName) {
AQH_MODULE *mTemp;
mTemp=AQH_Module_Tree2_GetFirstChild(m);
while(mTemp) {
const char *sModName;
sModName=AQH_Module_GetName(mTemp);
if (sModName && *sModName && 0==strcasecmp(sModName, sWantedName))
break;
mTemp=AQH_Module_Tree2_GetNext(mTemp);
}
if (mTemp==NULL) {
DBG_ERROR(NULL, "Module \%s\" not found", sWantedName);
GWEN_StringList_free(sl);
return NULL;
}
m=mTemp;
}
else {
DBG_ERROR(NULL, "Empty path element in \"%s\"", s);
GWEN_StringList_free(sl);
return NULL;
}
se=GWEN_StringListEntry_Next(se);
} /* while(se && m) */
GWEN_StringList_free(sl);
return m;
}
else {
DBG_ERROR(NULL, "Bad path \"%s\"", s);
}
}
return NULL;
}
#endif
int AQH_Service_HandleRequest(AQH_SERVICE *sv, AQCGI_REQUEST *req)
{
return (sv && sv->handleRequestFn)?(sv->handleRequestFn(sv, req)):GWEN_ERROR_NOT_IMPLEMENTED;
}
AQH_USER *AQH_Service_LoadUser(AQH_SERVICE *sv, const char *s)
{
return (sv && sv->loadUserFn)?(sv->loadUserFn(sv, s)):NULL;
}
int AQH_Service_SaveUser(AQH_SERVICE *sv, AQH_USER *user)
{
return (sv && sv->saveUserFn)?(sv->saveUserFn(sv, user)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQH_Service_AddUser(AQH_SERVICE *sv, AQH_USER *user)
{
return (sv && sv->addUserFn)?(sv->addUserFn(sv, user)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQH_Service_DelUser(AQH_SERVICE *sv, const char *s)
{
return (sv && sv->delUserFn)?(sv->delUserFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}
GWEN_STRINGLIST *AQH_Service_ListUsers(AQH_SERVICE *sv)
{
return (sv && sv->listUsersFn)?(sv->listUsersFn(sv)):NULL;
}
AQH_MODULE *AQH_Service_LoadModule(AQH_SERVICE *sv, const char *s)
{
return (sv && sv->loadModuleFn)?(sv->loadModuleFn(sv, s)):NULL;
}
int AQH_Service_SaveModule(AQH_SERVICE *sv, AQH_MODULE *module)
{
return (sv && sv->saveModuleFn)?(sv->saveModuleFn(sv, module)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQH_Service_AddModule(AQH_SERVICE *sv, AQH_MODULE *module)
{
return (sv && sv->addModuleFn)?(sv->addModuleFn(sv, module)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQH_Service_DelModule(AQH_SERVICE *sv, const char *s)
{
return (sv && sv->delModuleFn)?(sv->delModuleFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}
GWEN_STRINGLIST *AQH_Service_ListModules(AQH_SERVICE *sv)
{
return (sv && sv->listModulesFn)?(sv->listModulesFn(sv)):NULL;
}
AQH_SESSION* AQH_Service_LoadSession(AQH_SERVICE *sv, const char *s)
{
return (sv && sv->loadSessionFn)?(sv->loadSessionFn(sv, s)):NULL;
}
int AQH_Service_SaveSession(AQH_SERVICE *sv, AQH_SESSION *session)
{
return (sv && sv->saveSessionFn)?(sv->saveSessionFn(sv, session)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQH_Service_AddSession(AQH_SERVICE *sv, AQH_SESSION *session)
{
return (sv && sv->addSessionFn)?(sv->addSessionFn(sv, session)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQH_Service_DelSession(AQH_SERVICE *sv, const char *s)
{
return (sv && sv->delSessionFn)?(sv->delSessionFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}
void AQH_Service_SetHandleRequestFn(AQH_SERVICE *sv, AQH_SERVICE_HANDLEREQUEST_FN f)
{
if (sv)
sv->handleRequestFn=f;
}
void AQH_Service_SetLoadUserFn(AQH_SERVICE *sv, AQH_SERVICE_LOADUSER_FN f)
{
if (sv)
sv->loadUserFn=f;
}
void AQH_Service_SetSaveUserFn(AQH_SERVICE *sv, AQH_SERVICE_SAVEUSER_FN f)
{
if (sv)
sv->saveUserFn=f;
}
void AQH_Service_SetAddUserFn(AQH_SERVICE *sv, AQH_SERVICE_ADDUSER_FN f)
{
if (sv)
sv->addUserFn=f;
}
void AQH_Service_SetDelUserFn(AQH_SERVICE *sv, AQH_SERVICE_DELUSER_FN f)
{
if (sv)
sv->delUserFn=f;
}
void AQH_Service_SetListUsersFn(AQH_SERVICE *sv, AQH_SERVICE_LISTUSERS_FN f)
{
if (sv)
sv->listUsersFn=f;
}
void AQH_Service_SetLoadModuleFn(AQH_SERVICE *sv, AQH_SERVICE_LOADMODULE_FN f)
{
if (sv)
sv->loadModuleFn=f;
}
void AQH_Service_SetSaveModuleFn(AQH_SERVICE *sv, AQH_SERVICE_SAVEMODULE_FN f)
{
if (sv)
sv->saveModuleFn=f;
}
void AQH_Service_SetAddModuleFn(AQH_SERVICE *sv, AQH_SERVICE_ADDMODULE_FN f)
{
if (sv)
sv->addModuleFn=f;
}
void AQH_Service_SetDelModuleFn(AQH_SERVICE *sv, AQH_SERVICE_DELMODULE_FN f)
{
if (sv)
sv->delModuleFn=f;
}
void AQH_Service_SetListModulesFn(AQH_SERVICE *sv, AQH_SERVICE_LISTMODULES_FN f)
{
if (sv)
sv->listModulesFn=f;
}
void AQH_Service_SetLoadSessionFn(AQH_SERVICE *sv, AQH_SERVICE_LOADSESSION_FN f)
{
if (sv)
sv->loadSessionFn=f;
}
void AQH_Service_SetSaveSessionFn(AQH_SERVICE *sv, AQH_SERVICE_SAVESESSION_FN f)
{
if (sv)
sv->saveSessionFn=f;
}
void AQH_Service_SetAddSessionFn(AQH_SERVICE *sv, AQH_SERVICE_ADDSESSION_FN f)
{
if (sv)
sv->addSessionFn=f;
}
void AQH_Service_SetDelSessionFn(AQH_SERVICE *sv, AQH_SERVICE_DELSESSION_FN f)
{
if (sv)
sv->delSessionFn=f;
}
void AQH_Service_SetListSessionsFn(AQH_SERVICE *sv, AQH_SERVICE_LISTSESSIONS_FN f)
{
if (sv)
sv->listSessionsFn=f;
}

View File

@@ -1,107 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_SERVICE_H
#define AQHOME_SERVICE_H
#include <aqhome/api.h>
#include <gwenhywfar/inherit.h>
#include <gwenhywfar/list.h>
#include <gwenhywfar/stringlist.h>
typedef struct AQH_SERVICE AQH_SERVICE;
GWEN_INHERIT_FUNCTION_DEFS(AQH_SERVICE);
GWEN_LIST_FUNCTION_DEFS(AQH_SERVICE, AQH_Service);
#include "aqhome-cgi/service/user.h"
#include "aqhome-cgi/service/module.h"
#include "aqhome-cgi/service/session.h"
#include <aqcgi/cgi.h>
typedef int (*AQH_SERVICE_HANDLEREQUEST_FN)(AQH_SERVICE *sv, AQCGI_REQUEST *req);
typedef AQH_USER* (*AQH_SERVICE_LOADUSER_FN)(AQH_SERVICE *sv, const char *s);
typedef int (*AQH_SERVICE_SAVEUSER_FN)(AQH_SERVICE *sv, AQH_USER *user);
typedef int (*AQH_SERVICE_ADDUSER_FN)(AQH_SERVICE *sv, AQH_USER *user);
typedef int (*AQH_SERVICE_DELUSER_FN)(AQH_SERVICE *sv, const char *s);
typedef GWEN_STRINGLIST* (*AQH_SERVICE_LISTUSERS_FN)(AQH_SERVICE *sv);
typedef AQH_MODULE* (*AQH_SERVICE_LOADMODULE_FN)(AQH_SERVICE *sv, const char *s);
typedef int (*AQH_SERVICE_SAVEMODULE_FN)(AQH_SERVICE *sv, AQH_MODULE *module);
typedef int (*AQH_SERVICE_ADDMODULE_FN)(AQH_SERVICE *sv, AQH_MODULE *module);
typedef int (*AQH_SERVICE_DELMODULE_FN)(AQH_SERVICE *sv, const char *s);
typedef GWEN_STRINGLIST* (*AQH_SERVICE_LISTMODULES_FN)(AQH_SERVICE *sv);
typedef AQH_SESSION* (*AQH_SERVICE_LOADSESSION_FN)(AQH_SERVICE *sv, const char *s);
typedef int (*AQH_SERVICE_SAVESESSION_FN)(AQH_SERVICE *sv, AQH_SESSION *session);
typedef int (*AQH_SERVICE_ADDSESSION_FN)(AQH_SERVICE *sv, AQH_SESSION *session);
typedef int (*AQH_SERVICE_DELSESSION_FN)(AQH_SERVICE *sv, const char *s);
typedef GWEN_STRINGLIST* (*AQH_SERVICE_LISTSESSIONS_FN)(AQH_SERVICE *sv);
AQH_SERVICE *AQH_Service_new(const char *baseFolder, const char *baseUrl);
void AQH_Service_free(AQH_SERVICE *sv);
const char *AQH_Service_GetBaseUrl(const AQH_SERVICE *sv);
const char *AQH_Service_GetBaseFolder(const AQH_SERVICE *sv);
const char *AQH_Service_GetRuntimeFolder(const AQH_SERVICE *sv);
const char *AQH_Service_GetCacheFolder(const AQH_SERVICE *sv);
int AQH_Service_HandleRequest(AQH_SERVICE *sv, AQCGI_REQUEST *req);
AQH_USER *AQH_Service_LoadUser(AQH_SERVICE *sv, const char *s);
int AQH_Service_SaveUser(AQH_SERVICE *sv, AQH_USER *user);
int AQH_Service_AddUser(AQH_SERVICE *sv, AQH_USER *user);
int AQH_Service_DelUser(AQH_SERVICE *sv, const char *s);
GWEN_STRINGLIST *AQH_Service_ListUsers(AQH_SERVICE *sv);
AQH_MODULE *AQH_Service_LoadModule(AQH_SERVICE *sv, const char *s);
int AQH_Service_SaveModule(AQH_SERVICE *sv, AQH_MODULE *module);
int AQH_Service_AddModule(AQH_SERVICE *sv, AQH_MODULE *module);
int AQH_Service_DelModule(AQH_SERVICE *sv, const char *s);
GWEN_STRINGLIST *AQH_Service_ListModules(AQH_SERVICE *sv);
AQH_SESSION* AQH_Service_LoadSession(AQH_SERVICE *sv, const char *s);
int AQH_Service_SaveSession(AQH_SERVICE *sv, AQH_SESSION *session);
int AQH_Service_AddSession(AQH_SERVICE *sv, AQH_SESSION *session);
int AQH_Service_DelSession(AQH_SERVICE *sv, const char *s);
GWEN_STRINGLIST *AQH_Service_ListSessions(AQH_SERVICE *sv);
void AQH_Service_SetHandleRequestFn(AQH_SERVICE *sv, AQH_SERVICE_HANDLEREQUEST_FN f);
void AQH_Service_SetLoadUserFn(AQH_SERVICE *sv, AQH_SERVICE_LOADUSER_FN f);
void AQH_Service_SetSaveUserFn(AQH_SERVICE *sv, AQH_SERVICE_SAVEUSER_FN f);
void AQH_Service_SetAddUserFn(AQH_SERVICE *sv, AQH_SERVICE_ADDUSER_FN f);
void AQH_Service_SetDelUserFn(AQH_SERVICE *sv, AQH_SERVICE_DELUSER_FN f);
void AQH_Service_SetListUsersFn(AQH_SERVICE *sv, AQH_SERVICE_LISTUSERS_FN f);
void AQH_Service_SetLoadModuleFn(AQH_SERVICE *sv, AQH_SERVICE_LOADMODULE_FN f);
void AQH_Service_SetSaveModuleFn(AQH_SERVICE *sv, AQH_SERVICE_SAVEMODULE_FN f);
void AQH_Service_SetAddModuleFn(AQH_SERVICE *sv, AQH_SERVICE_ADDMODULE_FN f);
void AQH_Service_SetDelModuleFn(AQH_SERVICE *sv, AQH_SERVICE_DELMODULE_FN f);
void AQH_Service_SetListModulesFn(AQH_SERVICE *sv, AQH_SERVICE_LISTMODULES_FN f);
void AQH_Service_SetLoadSessionFn(AQH_SERVICE *sv, AQH_SERVICE_LOADSESSION_FN f);
void AQH_Service_SetSaveSessionFn(AQH_SERVICE *sv, AQH_SERVICE_SAVESESSION_FN f);
void AQH_Service_SetAddSessionFn(AQH_SERVICE *sv, AQH_SERVICE_ADDSESSION_FN f);
void AQH_Service_SetDelSessionFn(AQH_SERVICE *sv, AQH_SERVICE_DELSESSION_FN f);
void AQH_Service_SetListSessionsFn(AQH_SERVICE *sv, AQH_SERVICE_LISTSESSIONS_FN f);
#endif

View File

@@ -1,50 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_SERVICE_P_H
#define AQHOME_SERVICE_P_H
#include "aqhome-cgi/service/service.h"
struct AQH_SERVICE {
GWEN_INHERIT_ELEMENT(AQH_SERVICE);
GWEN_LIST_ELEMENT(AQH_SERVICE);
char *baseUrl;
char *baseFolder;
char *runtimeFolder;
char *cacheFolder;
AQH_SERVICE_HANDLEREQUEST_FN handleRequestFn;
AQH_SERVICE_LOADUSER_FN loadUserFn;
AQH_SERVICE_SAVEUSER_FN saveUserFn;
AQH_SERVICE_ADDUSER_FN addUserFn;
AQH_SERVICE_DELUSER_FN delUserFn;
AQH_SERVICE_LISTUSERS_FN listUsersFn;
AQH_SERVICE_LOADMODULE_FN loadModuleFn;
AQH_SERVICE_SAVEMODULE_FN saveModuleFn;
AQH_SERVICE_ADDMODULE_FN addModuleFn;
AQH_SERVICE_DELMODULE_FN delModuleFn;
AQH_SERVICE_LISTMODULES_FN listModulesFn;
AQH_SERVICE_LOADSESSION_FN loadSessionFn;
AQH_SERVICE_SAVESESSION_FN saveSessionFn;
AQH_SERVICE_ADDSESSION_FN addSessionFn;
AQH_SERVICE_DELSESSION_FN delSessionFn;
AQH_SERVICE_LISTSESSIONS_FN listSessionsFn;
};
#endif

View File

@@ -1,117 +0,0 @@
<?xml?>
<tm2>
<type id="AQH_SESSION" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQH_SESSION</identifier>
<prefix>AQH_Session</prefix>
<baseFileName>session</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="pre">gwenhywfar/timestamp.h</header>
<header type="sys" loc="post">aqhome-cgi/service/user.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQH_SESSION_RTFLAGS" prefix="AQH_SESSION_RTFLAGS_">
<item name="MODIFIED" value="0x00000001" />
</define>
</defines>
<members>
<member name="uid" type="char_ptr" maxlen="64">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="userAlias" type="char_ptr" maxlen="64">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="state" type="int" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="tempToken" type="char_ptr" maxlen="64">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="timestampLastAccess" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="user" type="AQH_USER">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<setflags>assign</setflags>
<getflags>none</getflags>
<flags>volatile nodup nocopy</flags>
</member>
<member name="runtimeFlags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags volatile</flags>
</member>
</members>
</type>
</tm2>

View File

@@ -1,164 +0,0 @@
<?xml?>
<tm2>
<type id="AQH_USER" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQH_USER</identifier>
<prefix>AQH_User</prefix>
<baseFileName>user</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
with_refcount
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="pre">gwenhywfar/timestamp.h</header>
<header type="sys" loc="post">aqhome-cgi/service/moduleperms.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQH_USER_FLAGS" prefix="AQH_USER_FLAGS_">
<item name="ADMIN" value="0x00000001" />
</define>
<define id="AQH_USER_RTFLAGS" prefix="AQH_USER_RTFLAGS_">
<item name="MODIFIED" value="0x00000001" />
<item name="PERMSCALC" value="0x00000002" />
</define>
</defines>
<enums>
<enum id="AQH_USER_STATE" prefix="AQH_UserState_">
<item name="suspended">
<descr>User suspended</descr>
</item>
<item name="waitForConfirmation">
<descr>Waiting for email confirmation</descr>
</item>
<item name="waitForApproval">
<descr>Waiting for approval by admin</descr>
</item>
<item name="active">
<descr>User active</descr>
</item>
</enum>
</enums>
<members>
<member name="id" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember sortbymember</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="state" type="int" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>sortbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own sortbymember</flags>
</member>
<member name="alias" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember sortbymember</flags>
</member>
<member name="hashedPassword" type="char_ptr" maxlen="128">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="email" type="char_ptr" maxlen="128">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember sortbymember</flags>
</member>
<member name="notes" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own sortbymember</flags>
</member>
<member name="timestampLastLogin" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own sortbymember</flags>
</member>
<member name="modulePermList" type="AQH_MODULE_PERMS_LIST">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<getflags>none</getflags>
<setflags>none</setflags>
<flags>own</flags>
</member>
<member name="runtimeFlags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>volatile with_flags</flags>
</member>
</members>
</type>
</tm2>

View File

@@ -35,7 +35,7 @@
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
GWEN_INHERIT(AQH_SERVICE, AQH_SERVICE_FILE) GWEN_INHERIT(AQCGI_SERVICE, AQH_SERVICE_FILE)
@@ -46,29 +46,29 @@ GWEN_INHERIT(AQH_SERVICE, AQH_SERVICE_FILE)
static void GWENHYWFAR_CB _freeData(void *bp, void *p); static void GWENHYWFAR_CB _freeData(void *bp, void *p);
static AQH_USER *_loadUser(AQH_SERVICE *sv, const char *s); static AQCGI_USER *_loadUser(AQCGI_SERVICE *sv, const char *s);
static int _saveUser(AQH_SERVICE *sv, AQH_USER *user); static int _saveUser(AQCGI_SERVICE *sv, AQCGI_USER *user);
static int _addUser(AQH_SERVICE *sv, AQH_USER *user); static int _addUser(AQCGI_SERVICE *sv, AQCGI_USER *user);
static int _delUser(AQH_SERVICE *sv, const char *s); static int _delUser(AQCGI_SERVICE *sv, const char *s);
static GWEN_STRINGLIST *_listUsers(AQH_SERVICE *sv); static GWEN_STRINGLIST *_listUsers(AQCGI_SERVICE *sv);
static AQH_MODULE *_loadModule(AQH_SERVICE *sv, const char *s); static AQCGI_MODULE *_loadModule(AQCGI_SERVICE *sv, const char *s);
static int _saveModule(AQH_SERVICE *sv, AQH_MODULE *module); static int _saveModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module);
static int _addModule(AQH_SERVICE *sv, AQH_MODULE *module); static int _addModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module);
static int _delModule(AQH_SERVICE *sv, const char *s); static int _delModule(AQCGI_SERVICE *sv, const char *s);
static GWEN_STRINGLIST *_listModules(AQH_SERVICE *sv); static GWEN_STRINGLIST *_listModules(AQCGI_SERVICE *sv);
static AQH_SESSION* _loadSession(AQH_SERVICE *sv, const char *s); static AQCGI_SESSION* _loadSession(AQCGI_SERVICE *sv, const char *s);
static int _saveSession(AQH_SERVICE *sv, AQH_SESSION *session); static int _saveSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session);
static int _addSession(AQH_SERVICE *sv, AQH_SESSION *session); static int _addSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session);
static int _delSession(AQH_SERVICE *sv, const char *s); static int _delSession(AQCGI_SERVICE *sv, const char *s);
static GWEN_STRINGLIST *_listSessions(AQH_SERVICE *sv); static GWEN_STRINGLIST *_listSessions(AQCGI_SERVICE *sv);
static GWEN_DB_NODE *_loadGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroupName); static GWEN_DB_NODE *_loadGroupLocked(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName);
static int _saveGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db); static int _saveGroupLocked(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db);
static int _addGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db); static int _addGroupLocked(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db);
static int _deleteGroup(AQH_SERVICE *sv, const char *groupName, const char *subGroupName); static int _deleteGroup(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName);
static GWEN_STRINGLIST *_listGroup(AQH_SERVICE *sv, const char *groupName); static GWEN_STRINGLIST *_listGroup(AQCGI_SERVICE *sv, const char *groupName);
//static void _logGroup(const char *groupName, const char *subGroupName, GWEN_DB_NODE *db); //static void _logGroup(const char *groupName, const char *subGroupName, GWEN_DB_NODE *db);
@@ -79,42 +79,42 @@ static GWEN_STRINGLIST *_listGroup(AQH_SERVICE *sv, const char *groupName);
* ------------------------------------------------------------------------------------------------ * ------------------------------------------------------------------------------------------------
*/ */
AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder, const char *baseUrl) AQCGI_SERVICE *AQH_ServiceFiles_new(const char *baseFolder, const char *baseUrl)
{ {
AQH_SERVICE *sv; AQCGI_SERVICE *sv;
AQH_SERVICE_FILE *xs; AQH_SERVICE_FILE *xs;
GWEN_BUFFER *dbuf; GWEN_BUFFER *dbuf;
sv=AQH_Service_new(baseFolder, baseUrl); sv=AQCGI_Service_new(baseFolder, baseUrl);
GWEN_NEW_OBJECT(AQH_SERVICE_FILE, xs); GWEN_NEW_OBJECT(AQH_SERVICE_FILE, xs);
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv, xs, _freeData); GWEN_INHERIT_SETDATA(AQCGI_SERVICE, AQH_SERVICE_FILE, sv, xs, _freeData);
AQH_Service_SetLoadUserFn(sv, _loadUser); AQCGI_Service_SetLoadUserFn(sv, _loadUser);
AQH_Service_SetSaveUserFn(sv, _saveUser); AQCGI_Service_SetSaveUserFn(sv, _saveUser);
AQH_Service_SetAddUserFn(sv, _addUser); AQCGI_Service_SetAddUserFn(sv, _addUser);
AQH_Service_SetDelUserFn(sv, _delUser); AQCGI_Service_SetDelUserFn(sv, _delUser);
AQH_Service_SetListUsersFn(sv, _listUsers); AQCGI_Service_SetListUsersFn(sv, _listUsers);
AQH_Service_SetLoadModuleFn(sv, _loadModule); AQCGI_Service_SetLoadModuleFn(sv, _loadModule);
AQH_Service_SetSaveModuleFn(sv, _saveModule); AQCGI_Service_SetSaveModuleFn(sv, _saveModule);
AQH_Service_SetAddModuleFn(sv, _addModule); AQCGI_Service_SetAddModuleFn(sv, _addModule);
AQH_Service_SetDelModuleFn(sv, _delModule); AQCGI_Service_SetDelModuleFn(sv, _delModule);
AQH_Service_SetListModulesFn(sv, _listModules); AQCGI_Service_SetListModulesFn(sv, _listModules);
AQH_Service_SetLoadSessionFn(sv, _loadSession); AQCGI_Service_SetLoadSessionFn(sv, _loadSession);
AQH_Service_SetSaveSessionFn(sv, _saveSession); AQCGI_Service_SetSaveSessionFn(sv, _saveSession);
AQH_Service_SetAddSessionFn(sv, _addSession); AQCGI_Service_SetAddSessionFn(sv, _addSession);
AQH_Service_SetDelSessionFn(sv, _delSession); AQCGI_Service_SetDelSessionFn(sv, _delSession);
AQH_Service_SetListSessionsFn(sv, _listSessions); AQCGI_Service_SetListSessionsFn(sv, _listSessions);
dbuf=GWEN_Buffer_new(0, 256, 0, 1); dbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(dbuf, "dir://%s", AQH_Service_GetRuntimeFolder(sv)); GWEN_Buffer_AppendArgs(dbuf, "dir://%s", AQCGI_Service_GetRuntimeFolder(sv));
DBG_ERROR(NULL, "Creating config mgr \"%s\"", GWEN_Buffer_GetStart(dbuf)); DBG_ERROR(NULL, "Creating config mgr \"%s\"", GWEN_Buffer_GetStart(dbuf));
xs->configMgr=GWEN_ConfigMgr_Factory(GWEN_Buffer_GetStart(dbuf)); xs->configMgr=GWEN_ConfigMgr_Factory(GWEN_Buffer_GetStart(dbuf));
if (xs->configMgr==NULL) { if (xs->configMgr==NULL) {
DBG_ERROR(NULL, "Error creating config mgr \"%s\"", GWEN_Buffer_GetStart(dbuf)); DBG_ERROR(NULL, "Error creating config mgr \"%s\"", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_free(dbuf); GWEN_Buffer_free(dbuf);
AQH_Service_free(sv); AQCGI_Service_free(sv);
return NULL; return NULL;
} }
GWEN_Buffer_free(dbuf); GWEN_Buffer_free(dbuf);
@@ -135,15 +135,15 @@ void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p)
AQH_USER *_loadUser(AQH_SERVICE *sv, const char *s) AQCGI_USER *_loadUser(AQCGI_SERVICE *sv, const char *s)
{ {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
db=_loadGroupLocked(sv, AQH_SERVICE_FILE_GROUP_USERS, s); db=_loadGroupLocked(sv, AQH_SERVICE_FILE_GROUP_USERS, s);
if (db) { if (db) {
AQH_USER *user; AQCGI_USER *user;
user=AQH_User_fromDb(db); user=AQCGI_User_fromDb(db);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
return user; return user;
} }
@@ -153,25 +153,23 @@ AQH_USER *_loadUser(AQH_SERVICE *sv, const char *s)
int _saveUser(AQH_SERVICE *sv, AQH_USER *user) int _saveUser(AQCGI_SERVICE *sv, AQCGI_USER *user)
{ {
const char *s; const char *s;
s=AQH_User_GetAlias(user); s=AQCGI_User_GetAlias(user);
if (s && *s) { if (s && *s) {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
int rv; int rv;
db=GWEN_DB_Group_new(s); db=GWEN_DB_Group_new(s);
rv=AQH_User_toDb(user, db); rv=AQCGI_User_toDb(user, db);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "here (%d)", rv); DBG_ERROR(NULL, "here (%d)", rv);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
return rv; return rv;
} }
//_logGroup(AQH_SERVICE_FILE_GROUP_USERS, s, db);
rv=_saveGroupLocked(sv, AQH_SERVICE_FILE_GROUP_USERS, s, db); rv=_saveGroupLocked(sv, AQH_SERVICE_FILE_GROUP_USERS, s, db);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "here (%d)", rv); DBG_ERROR(NULL, "here (%d)", rv);
@@ -186,17 +184,17 @@ int _saveUser(AQH_SERVICE *sv, AQH_USER *user)
int _addUser(AQH_SERVICE *sv, AQH_USER *user) int _addUser(AQCGI_SERVICE *sv, AQCGI_USER *user)
{ {
const char *s; const char *s;
s=AQH_User_GetAlias(user); s=AQCGI_User_GetAlias(user);
if (s && *s) { if (s && *s) {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
int rv; int rv;
db=GWEN_DB_Group_new(s); db=GWEN_DB_Group_new(s);
rv=AQH_User_toDb(user, db); rv=AQCGI_User_toDb(user, db);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "here (%d)", rv); DBG_ERROR(NULL, "here (%d)", rv);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
@@ -219,29 +217,29 @@ int _addUser(AQH_SERVICE *sv, AQH_USER *user)
int _delUser(AQH_SERVICE *sv, const char *s) int _delUser(AQCGI_SERVICE *sv, const char *s)
{ {
return _deleteGroup(sv, AQH_SERVICE_FILE_GROUP_USERS, s); return _deleteGroup(sv, AQH_SERVICE_FILE_GROUP_USERS, s);
} }
GWEN_STRINGLIST *_listUsers(AQH_SERVICE *sv) GWEN_STRINGLIST *_listUsers(AQCGI_SERVICE *sv)
{ {
return _listGroup(sv, AQH_SERVICE_FILE_GROUP_USERS); return _listGroup(sv, AQH_SERVICE_FILE_GROUP_USERS);
} }
AQH_MODULE *_loadModule(AQH_SERVICE *sv, const char *s) AQCGI_MODULE *_loadModule(AQCGI_SERVICE *sv, const char *s)
{ {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
db=_loadGroupLocked(sv, AQH_SERVICE_FILE_GROUP_MODULES, s); db=_loadGroupLocked(sv, AQH_SERVICE_FILE_GROUP_MODULES, s);
if (db) { if (db) {
AQH_MODULE *module; AQCGI_MODULE *module;
module=AQH_Module_fromDb(db); module=AQCGI_Module_fromDb(db);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
return module; return module;
} }
@@ -251,17 +249,17 @@ AQH_MODULE *_loadModule(AQH_SERVICE *sv, const char *s)
int _saveModule(AQH_SERVICE *sv, AQH_MODULE *module) int _saveModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module)
{ {
const char *s; const char *s;
s=AQH_Module_GetName(module); s=AQCGI_Module_GetName(module);
if (s && *s) { if (s && *s) {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
int rv; int rv;
db=GWEN_DB_Group_new(s); db=GWEN_DB_Group_new(s);
rv=AQH_Module_toDb(module, db); rv=AQCGI_Module_toDb(module, db);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "here (%d)", rv); DBG_ERROR(NULL, "here (%d)", rv);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
@@ -281,17 +279,17 @@ int _saveModule(AQH_SERVICE *sv, AQH_MODULE *module)
int _addModule(AQH_SERVICE *sv, AQH_MODULE *module) int _addModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module)
{ {
const char *s; const char *s;
s=AQH_Module_GetName(module); s=AQCGI_Module_GetName(module);
if (s && *s) { if (s && *s) {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
int rv; int rv;
db=GWEN_DB_Group_new(s); db=GWEN_DB_Group_new(s);
rv=AQH_Module_toDb(module, db); rv=AQCGI_Module_toDb(module, db);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "here (%d)", rv); DBG_ERROR(NULL, "here (%d)", rv);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
@@ -311,14 +309,14 @@ int _addModule(AQH_SERVICE *sv, AQH_MODULE *module)
int _delModule(AQH_SERVICE *sv, const char *s) int _delModule(AQCGI_SERVICE *sv, const char *s)
{ {
return _deleteGroup(sv, AQH_SERVICE_FILE_GROUP_MODULES, s); return _deleteGroup(sv, AQH_SERVICE_FILE_GROUP_MODULES, s);
} }
GWEN_STRINGLIST *_listModules(AQH_SERVICE *sv) GWEN_STRINGLIST *_listModules(AQCGI_SERVICE *sv)
{ {
return _listGroup(sv, AQH_SERVICE_FILE_GROUP_MODULES); return _listGroup(sv, AQH_SERVICE_FILE_GROUP_MODULES);
} }
@@ -326,15 +324,15 @@ GWEN_STRINGLIST *_listModules(AQH_SERVICE *sv)
AQH_SESSION* _loadSession(AQH_SERVICE *sv, const char *s) AQCGI_SESSION* _loadSession(AQCGI_SERVICE *sv, const char *s)
{ {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
db=_loadGroupLocked(sv, AQH_SERVICE_FILE_GROUP_SESSIONS, s); db=_loadGroupLocked(sv, AQH_SERVICE_FILE_GROUP_SESSIONS, s);
if (db) { if (db) {
AQH_SESSION *session; AQCGI_SESSION *session;
session=AQH_Session_fromDb(db); session=AQCGI_Session_fromDb(db);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
return session; return session;
} }
@@ -344,17 +342,17 @@ AQH_SESSION* _loadSession(AQH_SERVICE *sv, const char *s)
int _saveSession(AQH_SERVICE *sv, AQH_SESSION *session) int _saveSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session)
{ {
const char *s; const char *s;
s=AQH_Session_GetUid(session); s=AQCGI_Session_GetUid(session);
if (s && *s) { if (s && *s) {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
int rv; int rv;
db=GWEN_DB_Group_new(s); db=GWEN_DB_Group_new(s);
rv=AQH_Session_toDb(session, db); rv=AQCGI_Session_toDb(session, db);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "here (%d)", rv); DBG_ERROR(NULL, "here (%d)", rv);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
@@ -374,17 +372,17 @@ int _saveSession(AQH_SERVICE *sv, AQH_SESSION *session)
int _addSession(AQH_SERVICE *sv, AQH_SESSION *session) int _addSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session)
{ {
const char *s; const char *s;
s=AQH_Session_GetUid(session); s=AQCGI_Session_GetUid(session);
if (s && *s) { if (s && *s) {
GWEN_DB_NODE *db; GWEN_DB_NODE *db;
int rv; int rv;
db=GWEN_DB_Group_new(s); db=GWEN_DB_Group_new(s);
rv=AQH_Session_toDb(session, db); rv=AQCGI_Session_toDb(session, db);
if (rv<0) { if (rv<0) {
DBG_ERROR(NULL, "here (%d)", rv); DBG_ERROR(NULL, "here (%d)", rv);
GWEN_DB_Group_free(db); GWEN_DB_Group_free(db);
@@ -404,27 +402,27 @@ int _addSession(AQH_SERVICE *sv, AQH_SESSION *session)
int _delSession(AQH_SERVICE *sv, const char *s) int _delSession(AQCGI_SERVICE *sv, const char *s)
{ {
return _deleteGroup(sv, AQH_SERVICE_FILE_GROUP_SESSIONS, s); return _deleteGroup(sv, AQH_SERVICE_FILE_GROUP_SESSIONS, s);
} }
GWEN_STRINGLIST *_listSessions(AQH_SERVICE *sv) GWEN_STRINGLIST *_listSessions(AQCGI_SERVICE *sv)
{ {
return _listGroup(sv, AQH_SERVICE_FILE_GROUP_SESSIONS); return _listGroup(sv, AQH_SERVICE_FILE_GROUP_SESSIONS);
} }
GWEN_DB_NODE *_loadGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroupName) GWEN_DB_NODE *_loadGroupLocked(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName)
{ {
DBG_ERROR(NULL, "Lock and load group %s/%s", groupName, subGroupName); DBG_ERROR(NULL, "Lock and load group %s/%s", groupName, subGroupName);
if (sv && groupName && subGroupName) { if (sv && groupName && subGroupName) {
AQH_SERVICE_FILE *xs; AQH_SERVICE_FILE *xs;
xs=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv); xs=GWEN_INHERIT_GETDATA(AQCGI_SERVICE, AQH_SERVICE_FILE, sv);
if (xs) { if (xs) {
GWEN_DB_NODE *db=NULL; GWEN_DB_NODE *db=NULL;
int rv; int rv;
@@ -460,12 +458,12 @@ GWEN_DB_NODE *_loadGroupLocked(AQH_SERVICE *sv, const char *groupName, const cha
int _saveGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db) int _saveGroupLocked(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db)
{ {
if (sv && groupName && subGroupName && db) { if (sv && groupName && subGroupName && db) {
AQH_SERVICE_FILE *xs; AQH_SERVICE_FILE *xs;
xs=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv); xs=GWEN_INHERIT_GETDATA(AQCGI_SERVICE, AQH_SERVICE_FILE, sv);
if (xs) { if (xs) {
int rv; int rv;
@@ -498,12 +496,12 @@ int _saveGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGrou
int _addGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db) int _addGroupLocked(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName, GWEN_DB_NODE *db)
{ {
if (sv && groupName && subGroupName && db) { if (sv && groupName && subGroupName && db) {
AQH_SERVICE_FILE *xs; AQH_SERVICE_FILE *xs;
xs=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv); xs=GWEN_INHERIT_GETDATA(AQCGI_SERVICE, AQH_SERVICE_FILE, sv);
if (xs) { if (xs) {
int rv; int rv;
@@ -539,12 +537,12 @@ int _addGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroup
int _deleteGroup(AQH_SERVICE *sv, const char *groupName, const char *subGroupName) int _deleteGroup(AQCGI_SERVICE *sv, const char *groupName, const char *subGroupName)
{ {
if (sv && groupName && subGroupName) { if (sv && groupName && subGroupName) {
AQH_SERVICE_FILE *xs; AQH_SERVICE_FILE *xs;
xs=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv); xs=GWEN_INHERIT_GETDATA(AQCGI_SERVICE, AQH_SERVICE_FILE, sv);
if (xs) { if (xs) {
int rv; int rv;
@@ -561,12 +559,12 @@ int _deleteGroup(AQH_SERVICE *sv, const char *groupName, const char *subGroupNam
GWEN_STRINGLIST *_listGroup(AQH_SERVICE *sv, const char *groupName) GWEN_STRINGLIST *_listGroup(AQCGI_SERVICE *sv, const char *groupName)
{ {
if (sv && groupName) { if (sv && groupName) {
AQH_SERVICE_FILE *xs; AQH_SERVICE_FILE *xs;
xs=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv); xs=GWEN_INHERIT_GETDATA(AQCGI_SERVICE, AQH_SERVICE_FILE, sv);
if (xs) { if (xs) {
GWEN_STRINGLIST *sl; GWEN_STRINGLIST *sl;
int rv; int rv;

View File

@@ -10,10 +10,10 @@
#define AQHOME_SERVICE_FILE_H #define AQHOME_SERVICE_FILE_H
#include "aqhome-cgi/service/service.h" #include "aqcgi/service/service.h"
AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder, const char *baseUrl); AQCGI_SERVICE *AQH_ServiceFiles_new(const char *baseFolder, const char *baseUrl);

View File

@@ -18,6 +18,7 @@
#include "aqhome/msg/node/m_node.h" #include "aqhome/msg/node/m_node.h"
#include "aqhome/msg/node/m_sendstats.h" #include "aqhome/msg/node/m_sendstats.h"
#include "aqhome/msg/node/m_recvstats.h" #include "aqhome/msg/node/m_recvstats.h"
#include "aqhome/msg/node/m_memstats.h"
#include "aqhome/msg/node/m_value.h" #include "aqhome/msg/node/m_value.h"
#include "aqhome/msg/node/m_addr.h" #include "aqhome/msg/node/m_addr.h"
#include "aqhome/msg/node/m_device.h" #include "aqhome/msg/node/m_device.h"
@@ -44,6 +45,7 @@ static void _handleMsgValue(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg);
static void _handleAddressMsg(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _handleAddressMsg(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg);
static void _handleMsgComSendStat(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _handleMsgComSendStat(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg);
static void _handleMsgComRecvStat(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _handleMsgComRecvStat(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg);
static void _handleMsgMemStat(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg);
static void _handleMsgDevice(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _handleMsgDevice(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg);
static void _handleMsgFlashReady(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _handleMsgFlashReady(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg);
@@ -76,6 +78,7 @@ void AQH_NodeServer_NodeMsgToDb(AQH_OBJECT *o, const AQH_MESSAGE *msg)
switch(msgType) { switch(msgType) {
case AQH_MSG_TYPE_COMSENDSTATS: _handleMsgComSendStat(xo, msg); break; case AQH_MSG_TYPE_COMSENDSTATS: _handleMsgComSendStat(xo, msg); break;
case AQH_MSG_TYPE_COMRECVSTATS: _handleMsgComRecvStat(xo, msg); break; case AQH_MSG_TYPE_COMRECVSTATS: _handleMsgComRecvStat(xo, msg); break;
case AQH_MSG_TYPE_MEMSTATS: _handleMsgMemStat(xo, msg); break;
case AQH_MSG_TYPE_VALUE_REPORT: _handleMsgValue(xo, msg); break; case AQH_MSG_TYPE_VALUE_REPORT: _handleMsgValue(xo, msg); break;
case AQH_MSG_TYPE_NEED_ADDRESS: _handleAddressMsg(xo, msg); break; case AQH_MSG_TYPE_NEED_ADDRESS: _handleAddressMsg(xo, msg); break;
case AQH_MSG_TYPE_CLAIM_ADDRESS: _handleAddressMsg(xo, msg); break; case AQH_MSG_TYPE_CLAIM_ADDRESS: _handleAddressMsg(xo, msg); break;
@@ -195,6 +198,30 @@ void _handleMsgComRecvStat(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg)
void _handleMsgMemStat(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg)
{
AQH_NODE_INFO *ni;
uint32_t uid;
uid=AQH_MemStatsMessage_GetUid(msg);
ni=_getOrCreateNodeAndUpdateUidAddr(xo, msg, uid);
if (ni==NULL) {
DBG_INFO(AQH_LOGDOMAIN, "Error handling message");
}
AQH_NodeInfo_SetStatsStackUsed(ni, AQH_MemStatsMessage_GetStackUsage(msg));
AQH_NodeInfo_SetStatsBuffersUsed(ni, AQH_MemStatsMessage_GetBuffersUsed(msg));
AQH_NodeInfo_SetStatsMaxBuffersUsed(ni, AQH_MemStatsMessage_GetMaxBuffersUsed(msg));
AQH_NodeInfo_SetStatsRecvNoBuffer(ni, AQH_MemStatsMessage_GetRecvNoBufferErrors(msg));
AQH_NodeInfo_SetStatsHeapUsed(ni, AQH_MemStatsMessage_GetHeapUsed(msg));
AQH_NodeInfo_SetStatsHeapFree(ni, AQH_MemStatsMessage_GetHeapFree(msg));
AQH_NodeInfo_SetStatsXramSize(ni, AQH_MemStatsMessage_GetXramSize(msg));
AQH_NodeDb_SetModified(xo->nodeDb);
_updateTimestampLastChange(ni);
}
void _handleMsgDevice(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg) void _handleMsgDevice(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg)
{ {
AQH_NODE_INFO *ni; AQH_NODE_INFO *ni;

View File

@@ -250,18 +250,9 @@ AQHNODE_DEVICE *_readXmlDevice(GWEN_XMLNODE *deviceNode)
AQHNODE_VALUE_LIST *valueList; AQHNODE_VALUE_LIST *valueList;
valueList=_readXmlValueList(valuesNode); valueList=_readXmlValueList(valuesNode);
if (valueList==NULL) { if (valueList)
DBG_INFO(NULL, "here");
AQHNODE_Device_free(device);
return NULL;
}
AQHNODE_Device_SetValueList(device, valueList); AQHNODE_Device_SetValueList(device, valueList);
} }
else {
DBG_INFO(NULL, "No <values> element");
AQHNODE_Device_free(device);
return NULL;
}
return device; return device;
} }

View File

@@ -36,6 +36,7 @@
#define CONNCLEAN_INTERVAL_IN_SECS 2 #define CONNCLEAN_INTERVAL_IN_SECS 2
#define CONNCHECK_INTERVAL_IN_SECS 10 #define CONNCHECK_INTERVAL_IN_SECS 10
#define HEARTBEAT_INTERVAL_IN_SECS 120 /* every 2mins */
@@ -133,11 +134,13 @@ void _runService(AQH_OBJECT *aqh, AQH_EVENT_LOOP *eventLoop)
int timeout; int timeout;
time_t timeLastConnectionCleanup; time_t timeLastConnectionCleanup;
time_t timeLastConnCheck; time_t timeLastConnCheck;
time_t timeLastHeartbeat;
timeout=AQH_NodeServer_GetTimeout(aqh); timeout=AQH_NodeServer_GetTimeout(aqh);
timeStart=time(NULL); timeStart=time(NULL);
timeLastConnectionCleanup=time(NULL); timeLastConnectionCleanup=timeStart;
timeLastConnCheck=time(NULL); timeLastConnCheck=timeStart;
timeLastHeartbeat=timeStart;
while(!stopService) { while(!stopService) {
time_t now; time_t now;
@@ -162,6 +165,13 @@ void _runService(AQH_OBJECT *aqh, AQH_EVENT_LOOP *eventLoop)
timeLastConnCheck=now; timeLastConnCheck=now;
} }
if (_diffInSeconds(now, timeLastHeartbeat)>HEARTBEAT_INTERVAL_IN_SECS) {
DBG_INFO(NULL, "Sending heartbeat message");
AQH_NodeServer_SendHeartbeat(aqh);
timeLastHeartbeat=now;
}
if (timeout && (_diffInSeconds(now, timeStart)>timeout)) { if (timeout && (_diffInSeconds(now, timeStart)>timeout)) {
DBG_INFO(NULL, "Timeout"); DBG_INFO(NULL, "Timeout");
break; break;

View File

@@ -42,6 +42,7 @@
#include <aqhome/msg/node/m_recvstats.h> #include <aqhome/msg/node/m_recvstats.h>
#include <aqhome/msg/node/m_sendstats.h> #include <aqhome/msg/node/m_sendstats.h>
#include <aqhome/msg/node/m_memstats.h> #include <aqhome/msg/node/m_memstats.h>
#include <aqhome/msg/node/m_heartbeat.h>
#include <aqhome/data/value.h> #include <aqhome/data/value.h>
#include <gwenhywfar/args.h> #include <gwenhywfar/args.h>
@@ -457,7 +458,7 @@ void _readConfig(AQH_OBJECT *o, AQH_NODE_SERVER *xo, GWEN_DB_NODE *dbArgs)
AQH_NodeServer_SetDbFile(o, GWEN_DB_GetCharValue(dbArgs, "dbfile", 0, NULL)); AQH_NodeServer_SetDbFile(o, GWEN_DB_GetCharValue(dbArgs, "dbfile", 0, NULL));
AQH_NodeServer_SetLogFile(o, GWEN_DB_GetCharValue(dbArgs, "logfile", 0, NULL)); AQH_NodeServer_SetLogFile(o, GWEN_DB_GetCharValue(dbArgs, "logfile", 0, NULL));
AQH_NodeServer_SetDevicePath(o, GWEN_DB_GetCharValue(dbArgs, "device", 0, AQHOMED_DEFAULT_DEVICE)); AQH_NodeServer_SetDevicePath(o, readCharConfigWithAlt(dbArgs, "device", "ConfigFile/device", AQHOMED_DEFAULT_DEVICE));
AQH_NodeServer_SetTpcAddress(o, readCharConfigWithAlt(dbArgs, "tcpAddress", "ConfigFile/nodesAddress", NULL)); AQH_NodeServer_SetTpcAddress(o, readCharConfigWithAlt(dbArgs, "tcpAddress", "ConfigFile/nodesAddress", NULL));
AQH_NodeServer_SetTcpPort(o, readIntConfigWithAlt(dbArgs, "tcpPort", "ConfigFile/nodesPort", AQHOMED_DEFAULT_IPC_PORT, -1)); AQH_NodeServer_SetTcpPort(o, readIntConfigWithAlt(dbArgs, "tcpPort", "ConfigFile/nodesPort", AQHOMED_DEFAULT_IPC_PORT, -1));
@@ -811,6 +812,25 @@ void AQH_NodeServer_HandleTtyMsgs(AQH_OBJECT *o)
void AQH_NodeServer_SendHeartbeat(AQH_OBJECT *o)
{
AQH_NODE_SERVER *xo;
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_NODE_SERVER, o);
if (xo && xo->ttyEndpoint) {
AQH_MESSAGE *nodeMsg;
time_t t;
t=time(0);
nodeMsg=AQH_HeartbeatMessage_new(0xf0, 0x00, AQH_MSG_TYPE_HEARTBEAT, (uint32_t) t);
AQH_Endpoint_AddMsgOut(xo->ttyEndpoint, nodeMsg);
AQH_NodeServer_WriteTtyMsgToLogFile(o, nodeMsg, "sending");
DBG_ERROR(NULL, "Forwarding node message %d to node", AQH_NodeMessage_GetMsgType(nodeMsg));
}
}
void _handleMsgFromTty(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg) void _handleMsgFromTty(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg)
{ {
uint8_t code; uint8_t code;
@@ -963,8 +983,13 @@ void _forwardDataFromMemStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE
uid=AQH_MemStatsMessage_GetUid(msg); uid=AQH_MemStatsMessage_GetUid(msg);
_publishInt( xo, uid, "mem/buffersUsed", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetBuffersUsed(msg)); _publishInt(xo, uid, "mem/buffersUsed", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetBuffersUsed(msg));
_publishInt( xo, uid, "mem/maxBuffersUsed", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetMaxBuffersUsed(msg)); _publishInt(xo, uid, "mem/maxBuffersUsed", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetMaxBuffersUsed(msg));
_publishInt(xo, uid, "mem/stackused", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetStackUsage(msg));
_publishInt(xo, uid, "mem/buffersused", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetBuffersUsed(msg));
_publishInt(xo, uid, "mem/heapused", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetHeapUsed(msg));
_publishInt(xo, uid, "mem/heapfree", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetHeapFree(msg));
_publishInt(xo, uid, "mem/xramsize", AQH_ValueModality_Stats, NULL, AQH_MemStatsMessage_GetXramSize(msg));
} }

View File

@@ -57,6 +57,7 @@ void AQH_NodeServer_HandleClientMsgs(AQH_OBJECT *o);
void AQH_NodeServer_HandleBrokerMsgs(AQH_OBJECT *o); void AQH_NodeServer_HandleBrokerMsgs(AQH_OBJECT *o);
void AQH_NodeServer_CheckBrokerConnection(AQH_OBJECT *o); void AQH_NodeServer_CheckBrokerConnection(AQH_OBJECT *o);
void AQH_NodeServer_CheckTtyConnection(AQH_OBJECT *o); void AQH_NodeServer_CheckTtyConnection(AQH_OBJECT *o);
void AQH_NodeServer_SendHeartbeat(AQH_OBJECT *o);
/* getters and setters */ /* getters and setters */

View File

@@ -23,6 +23,7 @@
#include "aqhome/msg/msg_sysstats.h" #include "aqhome/msg/msg_sysstats.h"
#include "aqhome/msg/msg_ping.h" #include "aqhome/msg/msg_ping.h"
#include "aqhome/msg/msg_pong.h" #include "aqhome/msg/msg_pong.h"
#include "aqhome/msg/m_heartbeat.h"
#include "aqhome/msg/msg_needaddr.h" #include "aqhome/msg/msg_needaddr.h"
#include "aqhome/msg/msg_claimaddr.h" #include "aqhome/msg/msg_claimaddr.h"
#include "aqhome/msg/msg_haveaddr.h" #include "aqhome/msg/msg_haveaddr.h"
@@ -80,6 +81,7 @@ void AqHomed_LogTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg)
switch(msgType) { switch(msgType) {
case AQH_MSG_TYPE_PING: AQH_PingMsg_DumpToBuffer(msg, dbuf, "received"); break; case AQH_MSG_TYPE_PING: AQH_PingMsg_DumpToBuffer(msg, dbuf, "received"); break;
case AQH_MSG_TYPE_PONG: AQH_PongMsg_DumpToBuffer(msg, dbuf, "received"); break; case AQH_MSG_TYPE_PONG: AQH_PongMsg_DumpToBuffer(msg, dbuf, "received"); break;
case AQH_MSG_TYPE_HEARTBEAT: AQH_HeartbeatMessage_DumpToBuffer(msg, dbuf, "received"); break;
case AQH_MSG_TYPE_COMSENDSTATS: AQH_SendStatsMsg_DumpToBuffer(msg, dbuf, "received"); break; case AQH_MSG_TYPE_COMSENDSTATS: AQH_SendStatsMsg_DumpToBuffer(msg, dbuf, "received"); break;
case AQH_MSG_TYPE_COMRECVSTATS: AQH_RecvStatsMsg_DumpToBuffer(msg, dbuf, "received"); break; case AQH_MSG_TYPE_COMRECVSTATS: AQH_RecvStatsMsg_DumpToBuffer(msg, dbuf, "received"); break;
case AQH_MSG_TYPE_TWIBUSMEMBER: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break; case AQH_MSG_TYPE_TWIBUSMEMBER: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break;

View File

@@ -1 +0,0 @@
test/

View File

@@ -1,107 +0,0 @@
<?xml?>
<gwbuild>
<target type="Program" name="aqhome-storage" install="$(bindir)" >
<includes type="c" >
$(gwenhywfar_cflags)
-I$(topsrcdir)
-I$(topbuilddir)
-I$(builddir)
-I$(srcdir)
</includes>
<includes type="tm2" >
--include=$(builddir)
--include=$(srcdir)
</includes>
<setVar name="local/cflags">$(visibility_cflags)</setVar>
<setVar name="tm2flags" >
</setVar>
<setVar name="local/typefiles" >
</setVar>
<setVar name="local/built_sources" >
</setVar>
<setVar name="local/built_headers_pub">
</setVar>
<setVar name="local/built_headers_priv" >
</setVar>
<headers dist="true" >
aqhomestorage_p.h
aqhomestorage.h
init.h
init_http.h
init_mqtt.h
fini.h
loop.h
loop_http.h
loop_mqtt.h
cleanup.h
u_base.h
u_login.h
u_objects.h
u_objects_p.h
u_rooms.h
u_devices.h
u_mqtttopics.h
u_values.h
u_static.h
u_static_p.h
aqhomehttp.h
aqhomehttp_p.h
</headers>
<sources>
$(local/typefiles)
aqhomestorage.c
init.c
init_http.c
init_mqtt.c
fini.c
loop.c
loop_http.c
loop_mqtt.c
cleanup.c
u_base.c
u_login.c
u_objects.c
u_rooms.c
u_devices.c
u_mqtttopics.c
u_values.c
u_static.c
main.c
aqhomehttp.c
</sources>
<useTargets>
aqhome
</useTargets>
<libraries>
$(gwenhywfar_libs)
</libraries>
<subdirs>
</subdirs>
<extradist>
</extradist>
</target>
</gwbuild>

View File

@@ -1,68 +0,0 @@
TODO
- isolate storage service:
- remove http service from here
- add ipc service
- admin:
- add room/device/MQTT topic/value
- edit room/device/MQTT topic/value
- del room/device/MQTT topic/value
- get received topics
- list rooms/devices/MQTT topics/values
- getValues(valueId, timeFrom, timeUntil)
- addValue(valueId/valueName, timeStamp, value)
- aqhome-tool
- add ipc admin code to connect to ipc service
- create http service as stand-alone app or create PHP code which uses aqhome-tool
- connect to storage service for information/admin
- move http service into own folder
- isolate functions:
- getRoomList
- getDeviceList
- getTopicList
- addRoom/Device/Topic/Value
- delRoom/Device/Topic/Value
- editRoom/Device/Topic/Value
- aqhome-storage->aqhome-data
- aqhome-data
- only list of values
- manages datafiles only
- IPC (later secure ipc):
- get value list
- add value
- del value
- edit value
- add datapoint(valueId, timestamp, data)
- add datapoint(valueName, timestamp, data)
- getData(valueId, timeFrom, timeUntil)
- getLastData(valueId)
- aqhome-tool:
- add ipc code
- aqhome-mqttdata:
- use devices, topics and values from aqhome-storage
- derive valueid and data from mqtt messages
- send data to aqhome-data via ipc (later secure ipc)
- mqtt values:
- aliases (e.g. for doors: open=1.0, closed=0.0, tilted=0.5)
- later services only:
- aqhomed (tty, ipcd)
- aqhome-data (ipcd)
- aqhome-mqtt (mqttc, ipcd)
- aqhome-httpd (maybe; httpd, ipcc)

View File

@@ -1,191 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./aqhomehttp_p.h"
#include "aqhome/http/httpservice.h"
#include "aqhome/http/httpservice_http.h"
#include <gwenhywfar/db.h>
#include <gwenhywfar/buffer.h>
#include <gwenhywfar/text.h>
#include <gwenhywfar/debug.h>
GWEN_INHERIT(AQH_SERVICE, AQHOME_HTTP)
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeHttpService_Extend(AQH_SERVICE *sv)
{
AQHOME_HTTP *xsv;
GWEN_NEW_OBJECT(AQHOME_HTTP, xsv);
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQHOME_HTTP, sv, xsv, _freeData);
xsv->contentTree=AQH_HttpContent_new("root");
xsv->storageMutex=GWEN_Mutex_new();
}
void _freeData(void *bp, void *p)
{
AQHOME_HTTP *xsv;
xsv=(AQHOME_HTTP*) p;
xsv->storage=NULL;
AQH_HttpContent_free(xsv->contentTree);
xsv->contentTree=NULL;
GWEN_Mutex_free(xsv->storageMutex);
GWEN_FREE_OBJECT(xsv);
}
AQH_STORAGE *AqHomeHttpService_GetStorage(const AQH_SERVICE *sv)
{
if (sv) {
AQHOME_HTTP *xsv;
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
if (xsv)
return xsv->storage;
}
return NULL;
}
void AqHomeHttpService_SetStorage(AQH_SERVICE *sv, AQH_STORAGE *sto)
{
if (sv) {
AQHOME_HTTP *xsv;
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
if (xsv)
xsv->storage=sto;
}
}
AQH_HTTP_CONTENT *AqHomeHttpService_GetContentTree(const AQH_SERVICE *sv)
{
if (sv) {
AQHOME_HTTP *xsv;
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
if (xsv)
return xsv->contentTree;
}
return NULL;
}
void AqHomeHttpService_SetContentTree(AQH_SERVICE *sv, AQH_HTTP_CONTENT *c)
{
if (sv) {
AQHOME_HTTP *xsv;
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
if (xsv) {
AQH_HttpContent_free(xsv->contentTree);
xsv->contentTree=c;
}
}
}
void AqHomeHttpService_MarkStorageChanged(AQH_SERVICE *sv)
{
if (sv) {
AQHOME_HTTP *xsv;
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
if (xsv) {
AQH_Storage_AddRuntimeFlags(xsv->storage, AQH_STORAGE_RTFLAGS_MODIFIED);
}
}
}
int AqHomeHttpService_LockStorage(AQH_SERVICE *sv)
{
if (sv) {
AQHOME_HTTP *xsv;
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
if (xsv) {
int rv;
rv=GWEN_Mutex_Lock(xsv->storageMutex);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error obtaining lock on storage mutex");
return rv;
}
return 0;
}
}
return GWEN_ERROR_GENERIC;
}
int AqHomeHttpService_UnlockStorage(AQH_SERVICE *sv)
{
if (sv) {
AQHOME_HTTP *xsv;
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
if (xsv) {
int rv;
rv=GWEN_Mutex_Unlock(xsv->storageMutex);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error releasing lock on storage mutex");
return rv;
}
return 0;
}
}
return GWEN_ERROR_GENERIC;
}

View File

@@ -1,59 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_HTTP_H
#define AQHOME_HTTP_H
#include "aqhome/service/service.h"
#include "aqhome/data/storage.h"
#include "aqhome/http/content.h"
#include <gwenhywfar/endpoint.h>
#define AQHOME_HTTP_PERMS_LIST_ROOMS 0x00000001
#define AQHOME_HTTP_PERMS_LIST_DEVICES 0x00000002
#define AQHOME_HTTP_PERMS_LIST_VALUES 0x00000004
#define AQHOME_HTTP_PERMS_LIST_TOPICS 0x00000008
#define AQHOME_HTTP_PERMS_ADD_ROOM 0x00000100
#define AQHOME_HTTP_PERMS_ADD_DEVICE 0x00000200
#define AQHOME_HTTP_PERMS_ADD_VALUE 0x00000400
#define AQHOME_HTTP_PERMS_ADD_TOPIC 0x00000800
#define AQHOME_HTTP_PERMS_DEL_ROOM 0x00010000
#define AQHOME_HTTP_PERMS_DEL_DEVICE 0x00020000
#define AQHOME_HTTP_PERMS_DEL_VALUE 0x00040000
#define AQHOME_HTTP_PERMS_DEL_TOPIC 0x00080000
#define AQHOME_HTTP_PERMS_EDIT_ROOM 0x01000000
#define AQHOME_HTTP_PERMS_EDIT_DEVICE 0x02000000
#define AQHOME_HTTP_PERMS_EDIT_VALUE 0x04000000
#define AQHOME_HTTP_PERMS_EDIT_TOPIC 0x08000000
void AqHomeHttpService_Extend(AQH_SERVICE *sv);
AQH_STORAGE *AqHomeHttpService_GetStorage(const AQH_SERVICE *sv);
void AqHomeHttpService_SetStorage(AQH_SERVICE *sv, AQH_STORAGE *sto);
AQH_HTTP_CONTENT *AqHomeHttpService_GetContentTree(const AQH_SERVICE *sv);
void AqHomeHttpService_SetContentTree(AQH_SERVICE *sv, AQH_HTTP_CONTENT *c);
int AqHomeHttpService_LockStorage(AQH_SERVICE *sv);
int AqHomeHttpService_UnlockStorage(AQH_SERVICE *sv);
void AqHomeHttpService_MarkStorageChanged(AQH_SERVICE *sv);
#endif

View File

@@ -1,31 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_HTTP_P_H
#define AQHOME_HTTP_P_H
#include "./aqhomehttp.h"
#include <gwenhywfar/mutex.h>
typedef struct AQHOME_HTTP AQHOME_HTTP;
struct AQHOME_HTTP {
AQH_STORAGE *storage; /* do not release */
GWEN_MUTEX *storageMutex;
AQH_HTTP_CONTENT *contentTree;
};
#endif

View File

@@ -1,126 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./aqhomestorage_p.h"
#include <gwenhywfar/misc.h>
#include <gwenhywfar/debug.h>
AQHOME_STORAGE *AqHomeStorage_new()
{
AQHOME_STORAGE *aqh;
GWEN_NEW_OBJECT(AQHOME_STORAGE, aqh);
aqh->rootEndpoint=GWEN_MsgEndpoint_new("root", 0);
return aqh;
}
void AqHomeStorage_free(AQHOME_STORAGE *aqh)
{
if (aqh) {
AQH_Service_free(aqh->httpService);
aqh->httpService=NULL;
AQH_Storage_free(aqh->storage);
aqh->storage=NULL;
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
aqh->rootEndpoint=NULL;
aqh->ipcdEndpoint=NULL;
aqh->mqttEndpoint=NULL;
aqh->httpdEndpoint=NULL;
GWEN_DB_Group_free(aqh->dbArgs);
aqh->dbArgs=NULL;
free(aqh->pidFile);
GWEN_FREE_OBJECT(aqh);
}
}
GWEN_MSG_ENDPOINT *AqHomeStorage_GetRootEndpoint(const AQHOME_STORAGE *aqh)
{
return aqh?(aqh->rootEndpoint):NULL;
}
GWEN_MSG_ENDPOINT *AqHomeStorage_GetIpcdEndpoint(const AQHOME_STORAGE *aqh)
{
return aqh?(aqh->ipcdEndpoint):NULL;
}
GWEN_MSG_ENDPOINT *AqHomeStorage_GetMqttEndpoint(const AQHOME_STORAGE *aqh)
{
return aqh?(aqh->mqttEndpoint):NULL;
}
GWEN_MSG_ENDPOINT *AqHomeStorage_GetHttpdEndpoint(const AQHOME_STORAGE *aqh)
{
return aqh?(aqh->httpdEndpoint):NULL;
}
GWEN_DB_NODE *AqHomeStorage_GetDbArgs(const AQHOME_STORAGE *aqh)
{
return aqh?(aqh->dbArgs):NULL;
}
AQH_STORAGE *AqHomeStorage_GetStorage(const AQHOME_STORAGE *aqh)
{
return aqh?(aqh->storage):NULL;
}
const char *AqHomeStorage_GetPidFile(const AQHOME_STORAGE *aqh)
{
return aqh?aqh->pidFile:NULL;
}
void AqHomeStorage_SetPidFile(AQHOME_STORAGE *aqh, const char *s)
{
if (aqh) {
free(aqh->pidFile);
aqh->pidFile=s?strdup(s):NULL;
}
}
int AqHomeStorage_GetTimeout(const AQHOME_STORAGE *aqh)
{
return aqh?aqh->timeout:0;
}

View File

@@ -1,42 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_H
#define AQHOME_STORAGE_H
#include "aqhome/data/storage.h"
#include "aqhome/service/session.h"
#include "aqhome/http/httpservice.h"
#include <gwenhywfar/endpoint.h>
typedef struct AQHOME_STORAGE AQHOME_STORAGE;
AQHOME_STORAGE *AqHomeStorage_new();
void AqHomeStorage_free(AQHOME_STORAGE *aqh);
GWEN_MSG_ENDPOINT *AqHomeStorage_GetRootEndpoint(const AQHOME_STORAGE *aqh);
GWEN_MSG_ENDPOINT *AqHomeStorage_GetIpcdEndpoint(const AQHOME_STORAGE *aqh);
GWEN_MSG_ENDPOINT *AqHomeStorage_GetMqttEndpoint(const AQHOME_STORAGE *aqh);
GWEN_MSG_ENDPOINT *AqHomeStorage_GetHttpdEndpoint(const AQHOME_STORAGE *aqh);
GWEN_DB_NODE *AqHomeStorage_GetDbArgs(const AQHOME_STORAGE *aqh);
AQH_STORAGE *AqHomeStorage_GetStorage(const AQHOME_STORAGE *aqh);
const char *AqHomeStorage_GetPidFile(const AQHOME_STORAGE *aqh);
void AqHomeStorage_SetPidFile(AQHOME_STORAGE *aqh, const char *s);
int AqHomeStorage_GetTimeout(const AQHOME_STORAGE *aqh);
#endif

View File

@@ -1,59 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_P_H
#define AQHOME_STORAGE_P_H
#include "./aqhomestorage.h"
/* default values */
#define AQHOME_STORAGE_DEFAULT_PIDFILE "/var/run/aqhome-storage.pid"
#define AQHOME_STORAGE_DEFAULT_IPC_PORT 45455
#define AQHOME_STORAGE_DEFAULT_HTTP_PORT 45456
#define AQHOME_STORAGE_DEFAULT_MQTT_CLIENTID "AQHOMESTORAGE"
#define AQHOME_STORAGE_DEFAULT_MQTT_KEEPALIVE 600
#define AQHOME_STORAGE_DEFAULT_MQTT_PORT 1883
#define AQHOME_STORAGE_DEFAULT_CONFIGDIR "/var/lib/aqhomestorage/config"
#define AQHOME_STORAGE_DEFAULT_HTTP_SOURCEDIR "/var/lib/aqhomestorage/html"
#define AQHOME_STORAGE_DEFAULT_DATADIR "/var/lib/aqhomestorage/data"
#define AQHOME_STORAGE_DEFAULT_STATEFILE "/var/lib/aqhomestorage/config/statefile"
#define AQHOME_STORAGE_DEFAULT_MAXSESSIONAGE (30*60)
#define AQHOME_STORAGE_SITEHEADER "site-header.html"
#define AQHOME_STORAGE_SITEFOOTER "site-footer.html"
#define AQHOME_STORAGE_STATIC_RELFOLDER "static"
struct AQHOME_STORAGE {
GWEN_MSG_ENDPOINT *rootEndpoint;
GWEN_MSG_ENDPOINT *ipcdEndpoint; /* don't release, will be released by freeing rootEndpoint! */
GWEN_MSG_ENDPOINT *mqttEndpoint; /* don't release, will be released by freeing rootEndpoint! */
GWEN_MSG_ENDPOINT *httpdEndpoint; /* don't release, will be released by freeing rootEndpoint! */
GWEN_DB_NODE *dbArgs;
AQH_SERVICE *httpService;
AQH_STORAGE *storage;
char *pidFile;
int maxSessionAgeInSeconds;
int timeout; /* timeout for run e.g. inside valgrind */
};
#endif

View File

@@ -1,61 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./cleanup.h"
#include "./aqhomehttp.h"
#include "./aqhomestorage_p.h"
#include "aqhome/http/httpservice_conf.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeStorage_Cleanup(AQHOME_STORAGE *aqh)
{
int rv;
rv=AQH_HttpService_CleanupSessions(aqh->httpService, aqh->maxSessionAgeInSeconds);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
}
}

View File

@@ -1,25 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_CLEANUP_H
#define AQHOME_STORAGE_CLEANUP_H
#include "./aqhomestorage.h"
void AqHomeStorage_Cleanup(AQHOME_STORAGE *aqh);
#endif

View File

@@ -1,83 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./fini.h"
#include "./aqhomestorage_p.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint_tcpd.h>
#include <unistd.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void _disconnectTree(GWEN_MSG_ENDPOINT *ep);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeStorage_Fini(AQHOME_STORAGE *aqh)
{
if (aqh) {
if (aqh->rootEndpoint) {
_disconnectTree(aqh->rootEndpoint);
GWEN_MsgEndpoint_Disconnect(aqh->rootEndpoint);
}
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
aqh->rootEndpoint=NULL;
aqh->ipcdEndpoint=NULL;
aqh->httpdEndpoint=NULL;
aqh->mqttEndpoint=NULL;
if (aqh->pidFile)
remove(aqh->pidFile);
}
}
void _disconnectTree(GWEN_MSG_ENDPOINT *ep)
{
GWEN_MSG_ENDPOINT *epChild;
epChild=GWEN_MsgEndpoint_Tree2_GetFirstChild(ep);
while(epChild) {
_disconnectTree(epChild);
epChild=GWEN_MsgEndpoint_Tree2_GetNext(epChild);
} /* while */
GWEN_MsgEndpoint_Disconnect(ep);
}

View File

@@ -1,23 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_FINI_H
#define AQHOME_STORAGE_FINI_H
#include "./aqhomestorage.h"
void AqHomeStorage_Fini(AQHOME_STORAGE *aqh);
#endif

View File

@@ -1,5 +0,0 @@
</body>
</html>

View File

@@ -1,16 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<!-- copyright (c) 2023 by martin -->
<meta name="generator" content="FTE 1.1" />
<meta name="revised" content="martin,2023-07-23" />
<meta name="keywords" content="" />
<meta name="description" content="" />
<meta name="author" content="martin" />
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>AqHome Storage Service</title>
</head>
<body>

View File

@@ -1,506 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./init.h"
#include "./init_http.h"
#include "./init_mqtt.h"
#include "./aqhomestorage_p.h"
#include "./aqhomehttp.h"
#include "aqhome/msg/endpoint_tty.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/mqtt/endpoint_mqttc.h"
#include "aqhome/http/endpoint_http.h"
#include "aqhome/http/httpservice_conf.h"
#include "aqhome/http/httpservice_http.h"
#include "aqhome/http/httpservice.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint_tcpd.h>
#include <gwenhywfar/endpoint_msgio.h>
#include <gwenhywfar/directory.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <time.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
//#define I18N(msg) msg
#define I18S(msg) msg
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static int _setupFolders(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs);
static int _setupStorage(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs);
static void _setupIpc(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs);
static GWEN_MSG_ENDPOINT *_acceptIpcFn(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKET *sk, const GWEN_INETADDRESS *addr, void *data);
static int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs);
static int _createPidFile(const char *pidFilename);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
int AqHomeStorage_Init(AQHOME_STORAGE *aqh, int argc, char **argv)
{
GWEN_DB_NODE *dbArgs;
int rv;
const char *s;
dbArgs=GWEN_DB_Group_new("args");
rv=_readArgs(argc, argv, dbArgs);
if (rv<0) {
DBG_ERROR(NULL, "Error reading args (%d)", rv);
return rv;
}
aqh->dbArgs=dbArgs;
aqh->maxSessionAgeInSeconds=GWEN_DB_GetIntValue(dbArgs, "maxSessionAge", 0, AQHOME_STORAGE_DEFAULT_MAXSESSIONAGE);
aqh->timeout=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 0);
s=GWEN_DB_GetCharValue(dbArgs, "pidfile", 0, AQHOME_STORAGE_DEFAULT_PIDFILE);
if (s && *s) {
AqHomeStorage_SetPidFile(aqh, s);
rv=_createPidFile(s);
if (rv<0) {
DBG_ERROR(NULL, "Error creating PID file (%d)", rv);
return rv;
}
}
rv=_setupFolders(aqh, dbArgs);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_setupStorage(aqh, dbArgs);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
_setupIpc(aqh, dbArgs);
rv=AqHomeStorage_SetupMqtt(aqh, dbArgs);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=AqHomeStorage_SetupHttp(aqh, dbArgs);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
return 0;
}
int _setupFolders(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
{
const char *s;
GWEN_BUFFER *nameBuf;
int pos;
int rv;
s=GWEN_DB_GetCharValue(dbArgs, "cfgdir", 0, AQHOME_STORAGE_DEFAULT_CONFIGDIR);
if (!(s && *s)) {
DBG_ERROR(NULL, "Missing configuration folder");
return GWEN_ERROR_GENERIC;
}
nameBuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendString(nameBuf, s);
pos=GWEN_Buffer_GetPos(nameBuf);
rv=GWEN_Directory_GetPath(GWEN_Buffer_GetStart(nameBuf), GWEN_PATH_FLAGS_CHECKROOT);
if (rv<0) {
DBG_ERROR(NULL, "Error accessing configuration folder \"%s\"", GWEN_Buffer_GetStart(nameBuf));
GWEN_Buffer_free(nameBuf);
return GWEN_ERROR_GENERIC;
}
GWEN_Buffer_Crop(nameBuf, 0, pos);
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S "modules");
rv=GWEN_Directory_GetPath(GWEN_Buffer_GetStart(nameBuf), GWEN_PATH_FLAGS_CHECKROOT);
if (rv<0) {
DBG_ERROR(NULL, "Error accessing modules folder \"%s\"", GWEN_Buffer_GetStart(nameBuf));
GWEN_Buffer_free(nameBuf);
return GWEN_ERROR_GENERIC;
}
GWEN_Buffer_Crop(nameBuf, 0, pos);
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S "users");
rv=GWEN_Directory_GetPath(GWEN_Buffer_GetStart(nameBuf), GWEN_PATH_FLAGS_CHECKROOT);
if (rv<0) {
DBG_ERROR(NULL, "Error accessing configuration folder \"%s\"", GWEN_Buffer_GetStart(nameBuf));
GWEN_Buffer_free(nameBuf);
return GWEN_ERROR_GENERIC;
}
GWEN_Buffer_free(nameBuf);
return 0;
}
int _setupStorage(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
{
const char *dataFolder;
const char *stateFile;
dataFolder=GWEN_DB_GetCharValue(dbArgs, "dataFolder", 0, AQHOME_STORAGE_DEFAULT_DATADIR);
stateFile=GWEN_DB_GetCharValue(dbArgs, "stateFile", 0, NULL);
if (stateFile && *stateFile) {
AQH_STORAGE *sto;
int rv;
sto=AQH_Storage_new();
AQH_Storage_SetStateFile(sto, stateFile);
AQH_Storage_SetDataFileFolder(sto, (dataFolder && *dataFolder)?dataFolder:NULL);
rv=AQH_Storage_Init(sto);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQH_Storage_free(sto);
return rv;
}
aqh->storage=sto;
}
else {
DBG_ERROR(NULL, "No state file given");
return GWEN_ERROR_GENERIC;
}
return 0;
}
void _setupIpc(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
{
const char *tcpAddress;
int tcpPort;
tcpAddress=GWEN_DB_GetCharValue(dbArgs, "tcpAddress", 0, NULL);
tcpPort=GWEN_DB_GetIntValue(dbArgs, "tcpPort", 0, AQHOME_STORAGE_DEFAULT_IPC_PORT);
if (tcpAddress && *tcpAddress && tcpPort) {
GWEN_MSG_ENDPOINT *ep;
ep=GWEN_TcpdEndpoint_new(tcpAddress, tcpPort, NULL, 0);
GWEN_TcpdEndpoint_SetAcceptFn(ep, _acceptIpcFn, aqh);
GWEN_MsgEndpoint_Tree2_AddChild(aqh->rootEndpoint, ep);
aqh->ipcdEndpoint=ep;
}
}
GWEN_MSG_ENDPOINT *_acceptIpcFn(GWEN_MSG_ENDPOINT *ep,
GWEN_SOCKET *sk,
const GWEN_INETADDRESS *addr,
GWEN_UNUSED void *data)
{
/* AQHOME_STORAGE *aqh;
*
* aqh=(AQHOME_STORAGE*) data;
*/
DBG_INFO(NULL, "Incoming IPC connection");
return AQH_IpcEndpoint_CreateIpcTcpServiceForSocket(sk, NULL, 0);
}
int _createPidFile(const char *pidFilename)
{
FILE *f;
int pidfd;
if (remove(pidFilename)==0) {
DBG_ERROR(0, "Old PID file existed, removed. (Unclean shutdown?)");
}
#ifdef HAVE_SYS_STAT_H
pidfd = open(pidFilename, O_EXCL|O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (pidfd < 0) {
DBG_ERROR(NULL, "Could not create PID file \"%s\" (%s), aborting.", pidFilename, strerror(errno));
return GWEN_ERROR_IO;
}
f = fdopen(pidfd, "w");
#else /* HAVE_STAT_H */
f=fopen(pidFilename,"w+");
#endif /* HAVE_STAT_H */
/* write pid */
#ifdef HAVE_GETPID
fprintf(f,"%d\n",getpid());
#else
fprintf(f,"-1\n");
#endif
if (fclose(f)) {
DBG_ERROR(0, "Could not close PID file \"%s\" (%s), aborting.", pidFilename, strerror(errno));
return GWEN_ERROR_IO;
}
return 0;
}
int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs)
{
int rv;
const GWEN_ARGS args[]= {
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"cfgdir", /* name */
0, /* minnum */
1, /* maxnum */
"D", /* short option */
"cfgdir", /* long option */
I18S("Specify the configuration folder"),
I18S("Specify the configuration folder")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"tcpAddress", /* name */
0, /* minnum */
1, /* maxnum */
"t", /* short option */
"tcpaddress", /* long option */
I18S("Specify the TCP address to listen on (disabled if missing)"),
I18S("Specify the TCP address to listen on (disabled if missing)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Int, /* type */
"tcpPort", /* name */
0, /* minnum */
1, /* maxnum */
"P", /* short option */
"tcpport", /* long option */
I18S("Specify the TCP port to listen on"),
I18S("Specify the TCP port to listen on")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"mqttAddress", /* name */
0, /* minnum */
1, /* maxnum */
"ma", /* short option */
"mqttaddress", /* long option */
I18S("Specify the address of the MQTT server to connect to (disabled if missing)"),
I18S("Specify the address of the MQTT server to connect to (disabled if missing)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Int, /* type */
"mqttPort", /* name */
0, /* minnum */
1, /* maxnum */
"mp", /* short option */
"mqttport", /* long option */
I18S("Specify the port of the MQTT server (default: 1883)"),
I18S("Specify the port of the MQTT server (default: 1883)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"mqttClientId", /* name */
0, /* minnum */
1, /* maxnum */
NULL, /* short option */
"mqttclientid", /* long option */
I18S("Specify client id for the MQTT server (default: \"AQHOMESTORAGE\")"),
I18S("Specify client id for the MQTT server (default: \"AQHOMESTORAGE\")")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Int, /* type */
"mqttKeepAlive", /* name */
0, /* minnum */
1, /* maxnum */
"mk", /* short option */
"mqttkeepalive", /* long option */
I18S("Specify keepalive time in seconds (defaults: 600)"),
I18S("Specify keepalive time in seconds (defaults: 600)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"httpAddress", /* name */
0, /* minnum */
1, /* maxnum */
"ha", /* short option */
"httpaddress", /* long option */
I18S("Specify the address to bind the http service to (disabled if missing)"),
I18S("Specify the address to bind the http service to (disabled if missing)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Int, /* type */
"httpPort", /* name */
0, /* minnum */
1, /* maxnum */
"hp", /* short option */
"httpport", /* long option */
I18S("Specify the port to listen on for HTTP connections"),
I18S("Specify the port to listen on for HTTP connections")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Int, /* type */
"maxSessionAge", /* name */
0, /* minnum */
1, /* maxnum */
NULL, /* short option */
"maxsessionage", /* long option */
I18S("Specify maximum session age in seconds (default: 30mins)"),
I18S("Specify maximum session age in seconds (default: 30mins)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"sourcefolder", /* name */
0, /* minnum */
1, /* maxnum */
NULL, /* short option */
"sourcefolder", /* long option */
I18S("Folder where static HTML source files are stored"),
I18S("Folder where static HTML source files are stored")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"datafolder", /* name */
0, /* minnum */
1, /* maxnum */
NULL, /* short option */
"datafolder", /* long option */
I18S("Folder where data files are stored"),
I18S("Folder where data files are stored")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"statefile", /* name */
0, /* minnum */
1, /* maxnum */
"S", /* short option */
"statefile", /* long option */
I18S("File where rooms, devices and values etc. are stored"),
I18S("File where rooms, devices and values etc. are stored")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"pidfile", /* name */
0, /* minnum */
1, /* maxnum */
"p", /* short option */
"pidfile", /* long option */
I18S("Specify the PID file"),
I18S("Specify the PID file")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Int, /* type */
"timeout", /* name */
0, /* minnum */
1, /* maxnum */
"T", /* short option */
"timeout", /* long option */
I18S("Specify timeout in second (default: no timeout)"),
I18S("Specify timeout in second (default: no timeout)")
},
{
GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
GWEN_ArgsType_Int, /* type */
"help", /* name */
0, /* minnum */
0, /* maxnum */
"h", /* short option */
"help",
I18S("Show this help screen."),
I18S("Show this help screen.")
}
};
rv=GWEN_Args_Check(argc, argv, 1, 0, args, dbArgs);
if (rv==GWEN_ARGS_RESULT_ERROR) {
fprintf(stderr, "ERROR: Could not parse arguments main\n");
return GWEN_ERROR_INVALID;
}
else if (rv==GWEN_ARGS_RESULT_HELP) {
GWEN_BUFFER *ubuf;
ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
GWEN_Buffer_AppendArgs(ubuf,
I18N("This is version %s.\nUsage: %s [OPTIONS]\n\nOptions:\n"),
AQHOME_VERSION_STRING,
argv[0]);
if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
fprintf(stderr, "ERROR: Could not create help string\n");
return 1;
}
GWEN_Buffer_AppendString(ubuf, "\n");
fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf));
GWEN_Buffer_free(ubuf);
return GWEN_ERROR_CLOSE;
}
return 0;
}

View File

@@ -1,23 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_INIT_H
#define AQHOME_STORAGE_INIT_H
#include "./aqhomestorage.h"
int AqHomeStorage_Init(AQHOME_STORAGE *aqh, int argc, char **argv);
#endif

View File

@@ -1,336 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./init_http.h"
#include "./aqhomestorage_p.h"
#include "./aqhomehttp.h"
#include "./u_login.h"
#include "./u_rooms.h"
#include "./u_devices.h"
#include "./u_mqtttopics.h"
#include "./u_values.h"
#include "./u_static.h"
#include "aqhome/msg/endpoint_tty.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/mqtt/endpoint_mqttc.h"
#include "aqhome/http/endpoint_http.h"
#include "aqhome/http/httpservice_conf.h"
#include "aqhome/http/httpservice_http.h"
#include "aqhome/http/httpservice.h"
#include "aqhome/http/content_files.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint_tcpd.h>
#include <gwenhywfar/endpoint_msgio.h>
#include <gwenhywfar/directory.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <time.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
//#define I18N(msg) msg
#define I18S(msg) msg
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void _setupEndpoint(AQHOME_STORAGE *aqh, const char *tcpAddress, int tcpPort);
static int _setupHttpService(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs);
static int _createContentRoot(AQHOME_STORAGE *aqh);
static GWEN_MSG_ENDPOINT *_acceptHttpFn(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKET *sk, const GWEN_INETADDRESS *addr, void *data);
static int _createUrlHandler_login(AQHOME_STORAGE *aqh);
static int _createUrlHandler_rooms(AQHOME_STORAGE *aqh);
static int _createUrlHandler_devices(AQHOME_STORAGE *aqh);
static int _createUrlHandler_topics(AQHOME_STORAGE *aqh);
static int _createUrlHandler_values(AQHOME_STORAGE *aqh);
static int _createUrlHandler_static(AQHOME_STORAGE *aqh);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
int AqHomeStorage_SetupHttp(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
{
const char *tcpAddress;
int tcpPort;
tcpAddress=GWEN_DB_GetCharValue(dbArgs, "httpAddress", 0, NULL);
tcpPort=GWEN_DB_GetIntValue(dbArgs, "httpPort", 0, AQHOME_STORAGE_DEFAULT_HTTP_PORT);
if (tcpAddress && *tcpAddress && tcpPort) {
int rv;
_setupEndpoint(aqh, tcpAddress, tcpPort);
rv=_setupHttpService(aqh, dbArgs);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_createContentRoot(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_createUrlHandler_login(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_createUrlHandler_rooms(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_createUrlHandler_devices(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_createUrlHandler_topics(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_createUrlHandler_values(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=_createUrlHandler_static(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
}
return 0;
}
void _setupEndpoint(AQHOME_STORAGE *aqh, const char *tcpAddress, int tcpPort)
{
GWEN_MSG_ENDPOINT *ep;
ep=GWEN_TcpdEndpoint_new(tcpAddress, tcpPort, NULL, 0);
GWEN_TcpdEndpoint_SetAcceptFn(ep, _acceptHttpFn, aqh);
GWEN_MsgEndpoint_Tree2_AddChild(aqh->rootEndpoint, ep);
aqh->httpdEndpoint=ep;
}
int _setupHttpService(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
{
const char *configFolder;
const char *sourceFolder;
int rv;
configFolder=GWEN_DB_GetCharValue(dbArgs, "cfgdir", 0, AQHOME_STORAGE_DEFAULT_CONFIGDIR);
sourceFolder=GWEN_DB_GetCharValue(dbArgs, "sourceFolder", 0, AQHOME_STORAGE_DEFAULT_HTTP_SOURCEDIR);
aqh->httpService=AQH_HttpService_new(configFolder, sourceFolder);
AqHomeHttpService_Extend(aqh->httpService);
AqHomeHttpService_SetStorage(aqh->httpService, aqh->storage);
rv=AQH_HttpService_LoadConfig(aqh->httpService);
if (rv<0) {
DBG_ERROR(NULL, "Error loading config for HTTP service (%d)", rv);
return GWEN_ERROR_GENERIC;
}
AQH_HttpService_LoadAllSessions(aqh->httpService);
return 0;
}
GWEN_MSG_ENDPOINT *_acceptHttpFn(GWEN_MSG_ENDPOINT *ep,
GWEN_SOCKET *sk,
const GWEN_INETADDRESS *addr,
GWEN_UNUSED void *data)
{
GWEN_MSG_ENDPOINT *epIncoming;
/* AQHOME_STORAGE *aqh;
*
* aqh=(AQHOME_STORAGE*) data;
*/
DBG_INFO(NULL, "Incoming HTTP connection");
epIncoming=GWEN_MsgEndpoint_new("http", 0);
GWEN_MsgEndpoint_SetSocket(epIncoming, sk);
GWEN_MsgIoEndpoint_Extend(epIncoming);
AQH_HttpEndpoint_Extend(epIncoming, AQH_ENDPOINT_HTTP_FLAGS_PASSIVE);
return epIncoming;
}
int _createContentRoot(AQHOME_STORAGE *aqh)
{
const char *sourceFolder;
GWEN_BUFFER *nbuf1;
GWEN_BUFFER *nbuf2;
AQH_HTTP_CONTENT *c;
sourceFolder=AQH_HttpService_GetSourceFolder(aqh->httpService);
nbuf1=GWEN_Buffer_new(0, 256, 0, 1);
nbuf2=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendString(nbuf1, sourceFolder);
GWEN_Buffer_AppendString(nbuf1, GWEN_DIR_SEPARATOR_S AQHOME_STORAGE_SITEHEADER);
GWEN_Buffer_AppendString(nbuf2, sourceFolder);
GWEN_Buffer_AppendString(nbuf2, GWEN_DIR_SEPARATOR_S AQHOME_STORAGE_SITEFOOTER);
c=AQH_HttpContentFiles_new("root", GWEN_Buffer_GetStart(nbuf1), GWEN_Buffer_GetStart(nbuf2));
if (c==NULL) {
DBG_INFO(NULL,
"Unable to create content for root (header=[%s], footer=[%s])",
GWEN_Buffer_GetStart(nbuf1), GWEN_Buffer_GetStart(nbuf2));
GWEN_Buffer_free(nbuf2);
GWEN_Buffer_free(nbuf1);
return GWEN_ERROR_GENERIC;
}
AqHomeHttpService_SetContentTree(aqh->httpService, c);
GWEN_Buffer_free(nbuf2);
GWEN_Buffer_free(nbuf1);
return 0;
}
int _createUrlHandler_login(AQHOME_STORAGE *aqh)
{
AQH_HTTP_URLHANDLER *uh;
uh=AQH_LoginHttpUrlHandler_new(aqh->httpService);
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
AQH_HttpUrlHandler_AddUrlPattern(uh, "/login");
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
return 0;
}
int _createUrlHandler_rooms(AQHOME_STORAGE *aqh)
{
AQH_HTTP_URLHANDLER *uh;
uh=AQH_RoomsHttpUrlHandler_new(aqh->httpService);
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
AQH_HttpUrlHandler_AddUrlPattern(uh, "/rooms/*");
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
return 0;
}
int _createUrlHandler_devices(AQHOME_STORAGE *aqh)
{
AQH_HTTP_URLHANDLER *uh;
uh=AQH_DevicesHttpUrlHandler_new(aqh->httpService);
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
AQH_HttpUrlHandler_AddUrlPattern(uh, "/devices/*");
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
return 0;
}
int _createUrlHandler_topics(AQHOME_STORAGE *aqh)
{
AQH_HTTP_URLHANDLER *uh;
uh=AQH_MqttTopicsHttpUrlHandler_new(aqh->httpService);
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
AQH_HttpUrlHandler_AddUrlPattern(uh, "/mqtttopics/*");
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
return 0;
}
int _createUrlHandler_values(AQHOME_STORAGE *aqh)
{
AQH_HTTP_URLHANDLER *uh;
uh=AQH_ValuesHttpUrlHandler_new(aqh->httpService);
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
AQH_HttpUrlHandler_AddUrlPattern(uh, "/values/*");
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
return 0;
}
int _createUrlHandler_static(AQHOME_STORAGE *aqh)
{
AQH_HTTP_URLHANDLER *uh;
GWEN_BUFFER *nameBuf;
const char *sourceFolder;
sourceFolder=AQH_HttpService_GetSourceFolder(aqh->httpService);
nameBuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendString(nameBuf, sourceFolder);
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S AQHOME_STORAGE_STATIC_RELFOLDER GWEN_DIR_SEPARATOR_S "pics");
uh=AQH_StaticHttpUrlHandler_new(aqh->httpService, GWEN_Buffer_GetStart(nameBuf));
GWEN_Buffer_free(nameBuf);
AQH_HttpUrlHandler_AddUrlPattern(uh, "/pics/*");
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
return 0;
}

View File

@@ -1,23 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_INIT_HTTP_H
#define AQHOME_STORAGE_INIT_HTTP_H
#include "./aqhomestorage.h"
int AqHomeStorage_SetupHttp(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs);
#endif

View File

@@ -1,212 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./init_mqtt.h"
#include "./aqhomestorage_p.h"
#include "./aqhomehttp.h"
#include "./u_login.h"
#include "./u_rooms.h"
#include "./u_devices.h"
#include "./u_mqtttopics.h"
#include "./u_values.h"
#include "./u_static.h"
#include "aqhome/msg/endpoint_tty.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/mqtt/endpoint_mqttc.h"
#include <aqhome/mqtt/msg_mqtt_subscribe.h>
#include <aqhome/mqtt/msg_mqtt_suback.h>
#include "aqhome/http/endpoint_http.h"
#include "aqhome/http/httpservice_conf.h"
#include "aqhome/http/httpservice_http.h"
#include "aqhome/http/httpservice.h"
#include "aqhome/http/content_files.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint_tcpd.h>
#include <gwenhywfar/endpoint_msgio.h>
#include <gwenhywfar/directory.h>
#include <gwenhywfar/text.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <time.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
//#define I18N(msg) msg
#define I18S(msg) msg
#define AQHOME_STORAGE_DEFAULT_CMDTIMEOUT 10000
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static int _mqttConnect(GWEN_MSG_ENDPOINT *epTcp);
static int _subscribe(AQHOME_STORAGE *aqh, const char *topicFilter);
static GWEN_MSG *_awaitPacket(GWEN_MSG_ENDPOINT *epTcp, uint8_t expectedPacketType, int timeoutInSeconds);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
int AqHomeStorage_SetupMqtt(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
{
const char *mqttAddress;
int mqttPort;
const char *mqttClientId;
int mqttKeepAlive;
mqttAddress=GWEN_DB_GetCharValue(dbArgs, "mqttAddress", 0, NULL);
mqttPort=GWEN_DB_GetIntValue(dbArgs, "mqttPort", 0, AQHOME_STORAGE_DEFAULT_MQTT_PORT);
mqttClientId=GWEN_DB_GetCharValue(dbArgs, "mqttClientId", 0, AQHOME_STORAGE_DEFAULT_MQTT_CLIENTID);
mqttKeepAlive=GWEN_DB_GetIntValue(dbArgs, "mqttKeepAlive", 0, AQHOME_STORAGE_DEFAULT_MQTT_KEEPALIVE);
if (mqttAddress && *mqttAddress && mqttPort) {
GWEN_MSG_ENDPOINT *ep;
int rv;
ep=AQH_MqttClientEndpoint_new(mqttClientId, mqttAddress, mqttPort, NULL, 0);
AQH_MqttClientEndpoint_SetKeepAliveTime(ep, mqttKeepAlive);
GWEN_MsgEndpoint_Tree2_AddChild(aqh->rootEndpoint, ep);
aqh->mqttEndpoint=ep;
rv=_mqttConnect(ep);
if (rv<0) {
DBG_ERROR(NULL, "Error connecting to MQTT server %s:%d (%d)", mqttAddress, mqttPort, rv);
return rv;
}
rv=_subscribe(aqh, "#");
if (rv<0) {
DBG_ERROR(NULL, "Error subscribingconnecting to MQTT server %s:%d (%d)", mqttAddress, mqttPort, rv);
return rv;
}
}
return 0;
}
int _mqttConnect(GWEN_MSG_ENDPOINT *epTcp)
{
if (GWEN_MsgEndpoint_GetState(epTcp)==GWEN_MSG_ENDPOINT_STATE_UNCONNECTED) {
int rv;
rv=AQH_MqttClientEndpoint_StartConnect(epTcp);
if (rv<0 && rv!=GWEN_ERROR_IN_PROGRESS) {
DBG_ERROR(NULL, "Error starting to connect (%d)", rv);
return rv;
}
}
while(GWEN_MsgEndpoint_GetState(epTcp)!=GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
DBG_DEBUG(NULL, "Next loop");
GWEN_MsgEndpoint_IoLoop(epTcp, 2000); /* 2000 ms */
}
return 0;
}
int _subscribe(AQHOME_STORAGE *aqh, const char *topicFilter)
{
uint16_t pckId;
GWEN_MSG *msgOut;
GWEN_MSG *msgIn;
DBG_INFO(NULL, "Sending SUBSCRIBE %s", topicFilter);
pckId=AQH_MqttClientEndpoint_GetNextPacketId(aqh->mqttEndpoint);
msgOut=GWEN_SubscribeMqttMsg_new(AQH_MQTTMSG_MSGTYPE_SUBSCRIBE, pckId, topicFilter, 0);
if (msgOut==NULL) {
DBG_ERROR(NULL, "Error creating message");
return GWEN_ERROR_INTERNAL;
}
GWEN_MsgEndpoint_AddSendMessage(aqh->mqttEndpoint, msgOut);
DBG_INFO(NULL, "Waiting for response");
msgIn=_awaitPacket(aqh->mqttEndpoint, AQH_MQTTMSG_MSGTYPE_SUBACK, AQHOME_STORAGE_DEFAULT_CMDTIMEOUT);
if (msgIn) {
GWEN_BUFFER *buf;
buf=GWEN_Buffer_new(0, 256, 0, 1);
AQH_SubAckMqttMsg_DumpToBuffer(msgIn, buf, "received");
DBG_INFO(NULL, "%s", GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
GWEN_Msg_free(msgIn);
}
return 0;
}
GWEN_MSG *_awaitPacket(GWEN_MSG_ENDPOINT *epTcp, uint8_t expectedPacketType, int timeoutInSeconds)
{
time_t startTime;
startTime=time(NULL);
for (;;) {
GWEN_MSG *msg;
time_t now;
GWEN_MsgEndpoint_IoLoop(epTcp, 2000); /* 2000 ms */
msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp);
if (msg) {
if ((AQH_MqttMsg_GetMsgTypeAndFlags(msg) & 0xf0)==(expectedPacketType & 0xf0)) {
return msg;
}
else {
DBG_ERROR(NULL, "Received this message:");
GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 2);
}
GWEN_Msg_free(msg);
}
now=time(NULL);
if (now-startTime>timeoutInSeconds) {
DBG_INFO(NULL, "Timeout");
break;
}
}
return NULL;
}

View File

@@ -1,25 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_INIT_MQTT_H
#define AQHOME_STORAGE_INIT_MQTT_H
#include "./aqhomestorage.h"
int AqHomeStorage_SetupMqtt(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs);
#endif

View File

@@ -1,150 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./loop.h"
#include "./loop_http.h"
#include "./loop_mqtt.h"
#include "./aqhomehttp.h"
#include "./aqhomestorage_p.h"
#include "aqhome/http/httpservice_conf.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static int _writeModifiedSessions(AQHOME_STORAGE *aqh);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeStorage_Loop(AQHOME_STORAGE *aqh, int timeoutInMsecs)
{
if (aqh) {
GWEN_MsgEndpoint_ChildrenIoLoop(aqh->rootEndpoint, timeoutInMsecs);
AqHomeStorage_ReadAndHandleHttpMessages(aqh);
AqHomeStorage_ReadAndHandleMqttMessages(aqh);
// AqHomeStorage_ReadAndHandleIpcMessages(aqh);
}
}
int AqHomeStorage_WriteStorageIfChanged(AQHOME_STORAGE *aqh)
{
if (AQH_Storage_GetRuntimeFlags(aqh->storage) & AQH_STORAGE_RTFLAGS_MODIFIED) {
int rv;
DBG_INFO(NULL, "Storage modified, writing statefile");
rv=AqHomeHttpService_LockStorage(aqh->httpService);
if (rv<0) {
DBG_INFO(NULL, "Error locking storage (%d)", rv);
return rv;
}
rv=AQH_Storage_WriteState(aqh->storage);
if (rv<0) {
DBG_INFO(NULL, "Error writing state file (%d)", rv);
AqHomeHttpService_UnlockStorage(aqh->httpService);
return rv;
}
rv=AqHomeHttpService_UnlockStorage(aqh->httpService);
if (rv<0) {
DBG_INFO(NULL, "Error unlocking storage (%d)", rv);
return rv;
}
}
return 0;
}
int AqHomeStorage_WriteServiceIfChanged(AQHOME_STORAGE *aqh)
{
int rv;
rv=_writeModifiedSessions(aqh);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
return 0;
}
int _writeModifiedSessions(AQHOME_STORAGE *aqh)
{
AQH_SESSION_LIST *sessionList;
int rv;
rv=AQH_HttpService_LockSessions(aqh->httpService);
if (rv<0) {
DBG_INFO(NULL, "Error locking sessions (%d)", rv);
return rv;
}
sessionList=AQH_Service_GetSessionList(aqh->httpService);
if (sessionList) {
AQH_SESSION *session;
session=AQH_Session_List_First(sessionList);
while(session) {
if (AQH_Session_GetRuntimeFlags(session) & AQH_SESSION_RTFLAGS_MODIFIED) {
DBG_INFO(NULL, "Session \"%s\" modified, writing", AQH_Session_GetUid(session));
rv=AQH_HttpService_SaveSession(aqh->httpService, session);
if (rv<0) {
DBG_INFO(NULL, "Error writing session \"%s\" (%d)", AQH_Session_GetUid(session), rv);
}
else {
DBG_DEBUG(NULL, "Session \"%s\" written", AQH_Session_GetUid(session));
AQH_Session_SubRuntimeFlags(session, AQH_SESSION_RTFLAGS_MODIFIED);
}
}
session=AQH_Session_List_Next(session);
}
}
rv=AQH_HttpService_UnlockSessions(aqh->httpService);
if (rv<0) {
DBG_INFO(NULL, "Error unlocking sessions (%d)", rv);
return rv;
}
return 0;
}

View File

@@ -1,27 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_LOOP_H
#define AQHOME_STORAGE_LOOP_H
#include "./aqhomestorage.h"
void AqHomeStorage_Loop(AQHOME_STORAGE *aqh, int timeoutInMsecs);
int AqHomeStorage_WriteStorageIfChanged(AQHOME_STORAGE *aqh);
int AqHomeStorage_WriteServiceIfChanged(AQHOME_STORAGE *aqh);
#endif

View File

@@ -1,117 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./loop_http.h"
#include "./aqhomestorage_p.h"
#include "aqhome/msg/endpoint_tty.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/mqtt/endpoint_mqttc.h"
#include "aqhome/http/endpoint_http.h"
#include "aqhome/http/httpservice_http.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/text.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint_tcpd.h>
#include <gwenhywfar/endpoint_msgio.h>
#include <gwenhywfar/syncio.h>
#include <gwenhywfar/url.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <time.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
//#define I18N(msg) msg
#define I18S(msg) msg
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void _handleHttpEndpoint(AQHOME_STORAGE *aqh, GWEN_MSG_ENDPOINT *ep);
static void _handleHttpMsg(AQHOME_STORAGE *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msgReceived);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeStorage_ReadAndHandleHttpMessages(AQHOME_STORAGE *aqh)
{
if (aqh->httpdEndpoint) {
GWEN_MSG_ENDPOINT *ep;
ep=GWEN_MsgEndpoint_Tree2_GetFirstChild(aqh->httpdEndpoint);
while(ep) {
_handleHttpEndpoint(aqh, ep);
ep=GWEN_MsgEndpoint_Tree2_GetNext(ep);
}
}
}
void _handleHttpEndpoint(AQHOME_STORAGE *aqh, GWEN_MSG_ENDPOINT *ep)
{
GWEN_MSG *msg;
while( (msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(ep)) ) {
_handleHttpMsg(aqh, ep, msg);
GWEN_Msg_free(msg);
}
}
void _handleHttpMsg(AQHOME_STORAGE *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msgReceived)
{
GWEN_MSG *msgResponse;
msgResponse=AQH_HttpService_HandleHttpRequest(aqh->httpService, ep, msgReceived);
if (msgResponse) {
DBG_INFO(NULL, "Sending response message");
GWEN_MsgEndpoint_AddSendMessage(ep, msgResponse);
}
else {
DBG_INFO(NULL, "No response for message");
}
}

View File

@@ -1,110 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./loop_mqtt.h"
#include "./aqhomestorage_p.h"
#include "aqhome/mqtt/msg_mqtt_publish.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
//#define I18N(msg) msg
#define I18S(msg) msg
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void _handlePublishMsg(AQHOME_STORAGE *aqh, GWEN_MSG *msg);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeStorage_ReadAndHandleMqttMessages(AQHOME_STORAGE *aqh)
{
GWEN_MSG *msg;
while( (msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(aqh->mqttEndpoint)) ) {
if ((AQH_MqttMsg_GetMsgTypeAndFlags(msg) & 0xf0)==(AQH_MQTTMSG_MSGTYPE_PUBLISH & 0xf0)) {
_handlePublishMsg(aqh, msg);
}
else if ((AQH_MqttMsg_GetMsgTypeAndFlags(msg) & 0xf0)==(AQH_MQTTMSG_MSGTYPE_PINGRESP & 0xf0)) {
DBG_INFO(AQH_LOGDOMAIN, "PING response received");
}
else {
DBG_INFO(NULL, "Received unexpected MQTT message %02x", AQH_MqttMsg_GetMsgTypeAndFlags(msg));
}
GWEN_Msg_free(msg);
}
}
int AqHomeStorage_MqttPing(AQHOME_STORAGE *aqh)
{
GWEN_MSG *msgOut;
DBG_INFO(AQH_LOGDOMAIN, "Sending PING");
msgOut=GWEN_MqttMsg_new(AQH_MQTTMSG_MSGTYPE_PINGREQ, 0, NULL);
if (msgOut==NULL) {
DBG_ERROR(NULL, "Error creating message");
return GWEN_ERROR_INTERNAL;
}
GWEN_MsgEndpoint_AddSendMessage(aqh->mqttEndpoint, msgOut);
return 0;
}
void _handlePublishMsg(AQHOME_STORAGE *aqh, GWEN_MSG *msg)
{
char *topic;
char *value;
topic=AQH_PublishMqttMsg_ExtractTopic(msg);
value=AQH_PublishMqttMsg_ExtractValue(msg);
if (topic && value)
AQH_Storage_HandleMqttPublish(aqh->storage, topic, value);
else {
DBG_ERROR(NULL, "Either topic or value missing in PUBLISH msg");
}
free(value);
free(topic);
}

View File

@@ -1,23 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_MQTT_H
#define AQHOME_STORAGE_MQTT_H
#include "./aqhomestorage.h"
void AqHomeStorage_ReadAndHandleMqttMessages(AQHOME_STORAGE *aqh);
int AqHomeStorage_MqttPing(AQHOME_STORAGE *aqh);
#endif

View File

@@ -1,269 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <aqhome/api.h>
#include <aqhome/aqhome.h>
#include "./aqhomestorage.h"
#include "./init.h"
#include "./fini.h"
#include "./loop.h"
#include "./loop_mqtt.h"
#include "./cleanup.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/logger.h>
#include <gwenhywfar/cgui.h>
#include <gwenhywfar/debug.h>
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
//#define CLEANUP_INTERVAL_IN_SECS (5*60)
//#define WRITE_INTERVAL_IN_SECS (5*60)
#define CLEANUP_INTERVAL_IN_SECS (60)
#define WRITE_INTERVAL_IN_SECS (60)
#define PING_INTERVAL 120
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
#ifdef HAVE_SIGNAL_H
static int _setSignalHandlers(void);
static int _setupSigAction(struct sigaction *sa, int sig);
static void _signalHandler(int s);
#endif
static void _runService(AQHOME_STORAGE *aqh);
static void _writeCurrentState(AQHOME_STORAGE *aqh);
/* ------------------------------------------------------------------------------------------------
* static vars
* ------------------------------------------------------------------------------------------------
*/
#ifdef HAVE_SIGNAL_H
static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT;
#endif
static int stopService=0;
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
int main(int argc, char **argv)
{
int rv;
AQHOME_STORAGE *aqh;
GWEN_GUI *gui;
rv=GWEN_Init();
if (rv) {
fprintf(stderr, "ERROR: Unable to init Gwen.\n");
return 2;
}
GWEN_Logger_Open(0, "aqhome-storage", 0, GWEN_LoggerType_Console, GWEN_LoggerFacility_User);
//GWEN_Logger_SetLevel(0, GWEN_LoggerLevel_Warning);
GWEN_Logger_SetLevel(0, GWEN_LoggerLevel_Info);
rv=_setSignalHandlers();
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
rv=AQH_Init();
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return 2;
}
gui=GWEN_Gui_CGui_new();
GWEN_Gui_SetGui(gui);
aqh=AqHomeStorage_new();
rv=AqHomeStorage_Init(aqh, argc, argv);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return 2;
}
_runService(aqh);
AqHomeStorage_Fini(aqh);
AqHomeStorage_free(aqh);
GWEN_Gui_SetGui(NULL);
GWEN_Gui_free(gui);
return 0;
}
void _runService(AQHOME_STORAGE *aqh)
{
time_t timeStart;
time_t timeLastCleanup;
time_t timeLastWrite;
time_t timeLastPing;
int timeout;
timeout=AqHomeStorage_GetTimeout(aqh);
timeStart=time(NULL);
timeLastCleanup=time(NULL);
timeLastWrite=time(NULL);
timeLastPing=time(NULL);
while(!stopService) {
time_t now;
DBG_DEBUG(NULL, "Next loop");
AqHomeStorage_Loop(aqh, 2000);
now=time(NULL);
if (((int)difftime(now, timeLastCleanup))>CLEANUP_INTERVAL_IN_SECS) {
DBG_INFO(NULL, "Cleanup time");
AqHomeStorage_Cleanup(aqh);
timeLastCleanup=now;
}
if (((int)difftime(now, timeLastWrite))>WRITE_INTERVAL_IN_SECS) {
DBG_INFO(NULL, "Write time");
_writeCurrentState(aqh);
timeLastWrite=now;
}
if (timeout && ((int)difftime(now, timeLastPing))>timeout) {
DBG_INFO(NULL, "Sending ping");
AqHomeStorage_MqttPing(aqh);
timeLastPing=now;
}
if (timeout && ((int)difftime(now, timeStart))>timeout) {
DBG_INFO(NULL, "Timeout");
_writeCurrentState(aqh);
break;
}
} /* while */
}
void _writeCurrentState(AQHOME_STORAGE *aqh)
{
int rv;
rv=AqHomeStorage_WriteStorageIfChanged(aqh);
if (rv<0) {
DBG_ERROR(NULL, "ATTENTION: Could not write storage statefile (%d)", rv);
}
rv=AqHomeStorage_WriteServiceIfChanged(aqh);
if (rv<0) {
DBG_ERROR(NULL, "ATTENTION: Could not write current config (%d)", rv);
}
}
int _setSignalHandlers(void)
{
#ifdef HAVE_SIGNAL_H
int rv;
rv=_setupSigAction(&saINT, SIGINT);
if (rv)
return rv;
rv=_setupSigAction(&saTERM, SIGTERM);
if (rv)
return rv;
rv=_setupSigAction(&saHUP, SIGHUP);
if (rv)
return rv;
# ifdef SIGTSTP
rv=_setupSigAction(&saTSTP, SIGTSTP);
if (rv)
return rv;
# endif
# ifdef SIGCONT
rv=_setupSigAction(&saCONT, SIGCONT);
if (rv)
return rv;
# endif
#endif
return 0;
}
int _setupSigAction(struct sigaction *sa, int sig)
{
sa->sa_handler=_signalHandler;
sigemptyset(&sa->sa_mask);
sa->sa_flags=0;
if (sigaction(sig, sa, 0)) {
DBG_ERROR(NULL, "Could not setup signal handler for signal %d", sig);
return GWEN_ERROR_IO;
}
return 0;
}
void _signalHandler(int s)
{
switch(s) {
case SIGINT:
case SIGTERM:
case SIGHUP:
DBG_WARN(0, "Received signal %d, stopping service in next loop.",s);
stopService=1;
break;
default:
DBG_WARN(0, "Unknown signal %d",s);
break;
}
}

View File

@@ -1,71 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./u_base.h"
#include "./aqhomehttp.h"
#include "aqhome/http/httpservice_http.h"
#include <gwenhywfar/debug.h>
#include <gwenhywfar/i18n.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
GWEN_MSG *AQH_BaseHttpUrlHandler_CreateResponseForErrorCode(AQH_HTTP_URLHANDLER *uh,
AQH_HTTP_REQUEST *rq,
int rv,
AQH_HTTP_URLHANDLER_WRITEPAGE_CB cb,
GWEN_DB_NODE *db)
{
if (rv<0) {
switch(rv) {
case GWEN_ERROR_INVALID:
return AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Missing fields"), 1, db, cb);
case GWEN_ERROR_FOUND:
return AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Object already exists"), 1, db, cb);
case GWEN_ERROR_NOT_FOUND:
return AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Object not found"), 1, db, cb);
case GWEN_ERROR_IO:
case GWEN_ERROR_INTERNAL:
default:
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh),
500, "Internal error",
AQH_HttpRequest_GetProtocol(rq), NULL);
}
}
return NULL;
}

View File

@@ -1,27 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_U_BASE_H
#define AQHOME_STORAGE_U_BASE_H
#include "aqhome/http/urlhandler.h"
GWEN_MSG *AQH_BaseHttpUrlHandler_CreateResponseForErrorCode(AQH_HTTP_URLHANDLER *uh,
AQH_HTTP_REQUEST *rq,
int rv,
AQH_HTTP_URLHANDLER_WRITEPAGE_CB cb,
GWEN_DB_NODE *db);
#endif

View File

@@ -1,351 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./u_devices.h"
#include "./u_objects.h"
#include "./aqhomehttp.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/i18n.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static int _addOrEditObject(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *db, int id);
static GWEN_DB_NODE *_findObjectByIdAndReturnAsDb(AQH_HTTP_URLHANDLER *uh, int id);
static int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf);
static int _writeEditPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf);
static void _listObjectsIntoBuffer(AQH_HTTP_URLHANDLER *uh, GWEN_BUFFER *pageBuf);
static void _writeEditingTable(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf);
static void _setFromObject(AQH_DEVICE *device, const AQH_DEVICE *srcDevice);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
AQH_HTTP_URLHANDLER *AQH_DevicesHttpUrlHandler_new(AQH_SERVICE *sv)
{
AQH_HTTP_URLHANDLER *uh;
uh=AQH_ObjectsHttpUrlHandler_new(sv,
AQHOME_HTTP_PERMS_LIST_DEVICES,
AQHOME_HTTP_PERMS_ADD_DEVICE,
AQHOME_HTTP_PERMS_DEL_DEVICE,
AQHOME_HTTP_PERMS_EDIT_DEVICE,
"/devices/list");
AQH_ObjectsHttpUrlHandler_SetAddOrEditObjectFn(uh, _addOrEditObject);
AQH_ObjectsHttpUrlHandler_SetFindObjectByIdAndReturnAsDbFn(uh, _findObjectByIdAndReturnAsDb);
AQH_ObjectsHttpUrlHandler_SetWriteAddPageFn(uh, _writeAddPage);
AQH_ObjectsHttpUrlHandler_SetWriteEditPageFn(uh, _writeEditPage);
AQH_ObjectsHttpUrlHandler_SetListObjectsIntoBufferFn(uh, _listObjectsIntoBuffer);
return uh;
}
int _addOrEditObject(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *db, int id)
{
AQH_SERVICE *sv;
AQH_STORAGE *sto;
AQH_DEVICE *newDevice;
const char *deviceName;
int rv;
sv=AQH_HttpUrlHandler_GetHttpService(uh);
sto=AqHomeHttpService_GetStorage(sv);
newDevice=AQH_Device_fromDb(db);
deviceName=AQH_Device_GetName(newDevice);
if (!(deviceName && *deviceName)) {
DBG_INFO(NULL, "Missing device name");
AQH_Device_free(newDevice);
return GWEN_ERROR_INVALID;
}
rv=AqHomeHttpService_LockStorage(sv);
if (rv<0) {
DBG_ERROR(NULL, "Error locking storage");
AQH_Device_free(newDevice);
return GWEN_ERROR_IO;
}
if (id>0) {
AQH_DEVICE *device;
DBG_INFO(NULL, "Edit existing device");
device=AQH_Storage_GetDeviceById(sto, id);
if (device==NULL) {
AqHomeHttpService_UnlockStorage(sv);
DBG_ERROR(NULL, "Device %d not found", id);
AQH_Device_free(newDevice);
return GWEN_ERROR_NOT_FOUND;
}
AQH_Device_SetId(device, id);
_setFromObject(device, newDevice);
AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED);
}
else {
AQH_DEVICE *device;
DBG_INFO(NULL, "Adding new device");
device=AQH_Storage_GetDeviceByName(sto, deviceName);
if (device) {
AqHomeHttpService_UnlockStorage(sv);
DBG_ERROR(NULL, "Device %s exists", deviceName);
AQH_Device_free(newDevice);
return GWEN_ERROR_FOUND;
}
device=AQH_Device_new();
AQH_Device_SetId(device, 0);
_setFromObject(device, newDevice);
AQH_Storage_AddDevice(sto, device);
AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED);
}
AQH_Device_free(newDevice);
rv=AqHomeHttpService_UnlockStorage(sv);
if (rv<0) {
DBG_ERROR(NULL, "Error unlocking storage");
return GWEN_ERROR_IO;
}
return 0;
}
void _setFromObject(AQH_DEVICE *device, const AQH_DEVICE *srcDevice)
{
AQH_Device_SetRoomId(device, AQH_Device_GetRoomId(srcDevice));
AQH_Device_SetName(device, AQH_Device_GetName(srcDevice));
AQH_Device_SetDeviceType(device, AQH_Device_GetDeviceType(srcDevice));
AQH_Device_SetLocation(device, AQH_Device_GetLocation(srcDevice));
AQH_Device_SetDescription(device, AQH_Device_GetDescription(srcDevice));
}
GWEN_DB_NODE *_findObjectByIdAndReturnAsDb(AQH_HTTP_URLHANDLER *uh, int id)
{
AQH_SERVICE *sv;
AQH_STORAGE *sto;
const AQH_DEVICE *device;
sv=AQH_HttpUrlHandler_GetHttpService(uh);
sto=AqHomeHttpService_GetStorage(sv);
device=AQH_Storage_GetDeviceById(sto, id);
if (device) {
GWEN_DB_NODE *db;
db=GWEN_DB_Group_new("device");
AQH_Device_toDb(device, db);
return db;
}
return NULL;
}
int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf)
{
GWEN_Buffer_AppendArgs(pageBuf,
"<h2>%s</h2><br>\n"
"<form action=\"/devices/add\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">",
I18N("Add Device"));
_writeEditingTable(uh, dbValues, pageBuf);
GWEN_Buffer_AppendArgs(pageBuf, "<input type=\"submit\" value=\"%s\"></form>", I18N("Submit"));
return 0;
}
int _writeEditPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf)
{
GWEN_Buffer_AppendArgs(pageBuf,
"<h2>%s</h2><br>\n"
"<form action=\"/devices/edit/%lu\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">",
I18N("Edit Device"),
(long unsigned int)(dbValues?GWEN_DB_GetIntValue(dbValues, "id", 0, 0):0));
_writeEditingTable(uh, dbValues, pageBuf);
GWEN_Buffer_AppendArgs(pageBuf, "<input type=\"submit\" value=\"%s\"></form>", I18N("Submit"));
return 0;
}
void _writeEditingTable(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf)
{
AQH_SERVICE *sv;
AQH_STORAGE *sto;
const AQH_ROOM_LIST *roomList;
unsigned long int selectedRoomId=0;
char numbuf[16];
sv=AQH_HttpUrlHandler_GetHttpService(uh);
sto=AqHomeHttpService_GetStorage(sv);
roomList=AQH_Storage_GetRoomList(sto);
selectedRoomId=(unsigned long int)(dbValues?GWEN_DB_GetIntValue(dbValues, "roomId", 0, 0):0);
snprintf(numbuf, sizeof(numbuf)-1, "%lu", selectedRoomId);
numbuf[sizeof(numbuf)-1]=0;
GWEN_Buffer_AppendArgs(pageBuf,
" <table>"
" <tr>"
" <td><label for=\"name\">%s: </label></td>"
" <td><input type=\"text\" name=\"name\" value=\"%s\" required></td>"
" </tr>",
I18N("Name"),
dbValues?GWEN_DB_GetCharValue(dbValues, "name", 0, ""):"");
GWEN_Buffer_AppendArgs(pageBuf,
"<tr><td><label for=\"roomId\">%s: </label></td>"
"<td><select id=\"roomId\" name=\"roomId\">",
I18N("Room"));
GWEN_Buffer_AppendArgs(pageBuf, "<option value=\"0\">%s</option>", I18N("-- select room --"));
if (roomList) {
const AQH_ROOM *r;
r=AQH_Room_List_First(roomList);
while(r) {
const char *roomName;
roomName=AQH_Room_GetName(r);
if (roomName && *roomName) {
snprintf(numbuf, sizeof(numbuf)-1, "%lu", (unsigned long int) AQH_Room_GetId(r));
numbuf[sizeof(numbuf)-1]=0;
if (selectedRoomId && AQH_Room_GetId(r)==selectedRoomId)
GWEN_Buffer_AppendArgs(pageBuf, "<option value=\"%s\" selected>%s</option>", numbuf, roomName);
else
GWEN_Buffer_AppendArgs(pageBuf, "<option value=\"%s\">%s</option>", numbuf, roomName);
}
r=AQH_Room_List_Next(r);
}
}
GWEN_Buffer_AppendString(pageBuf, "</select></td></tr>");
GWEN_Buffer_AppendArgs(pageBuf,
" <tr>"
" <td><label for=\"deviceType\">%s: </label></td>"
" <td><input type=\"text\" name=\"deviceType\" value=\"%s\"></td>"
" </tr>",
I18N("Type"),
dbValues?GWEN_DB_GetCharValue(dbValues, "deviceType", 0, ""):"");
GWEN_Buffer_AppendArgs(pageBuf,
" <tr>"
" <td><label for=\"location\">%s: </label></td>"
" <td><input type=\"text\" name=\"location\" value=\"%s\"></td>"
" </tr>",
I18N("Location"),
dbValues?GWEN_DB_GetCharValue(dbValues, "location", 0, ""):"");
GWEN_Buffer_AppendArgs(pageBuf,
" <tr>"
" <td><label for=\"description\">%s: </label></td>"
" <td><input type=\"text\" name=\"description\" value=\"%s\"></td>"
" </tr>"
" </table>",
I18N("Description"),
dbValues?GWEN_DB_GetCharValue(dbValues, "description", 0, ""):"");
}
void _listObjectsIntoBuffer(AQH_HTTP_URLHANDLER *uh, GWEN_BUFFER *pageBuf)
{
AQH_SERVICE *sv;
AQH_STORAGE *sto;
const AQH_DEVICE_LIST *rl;
sv=AQH_HttpUrlHandler_GetHttpService(uh);
sto=AqHomeHttpService_GetStorage(sv);
GWEN_Buffer_AppendArgs(pageBuf,
"<h2>%s</h2>"
"<table class=\"dataTable\">"
"<thead>"
" <tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th></th></tr>"
"</thead>",
I18N("Devices"),
I18N("Name"),
I18N("Room"),
I18N("Type"),
I18N("Location"),
I18N("Description"));
GWEN_Buffer_AppendString(pageBuf, "<tbody>");
rl=AQH_Storage_GetDeviceList(sto);
if (rl) {
const AQH_DEVICE *device;
device=AQH_Device_List_First(rl);
while(device) {
long unsigned int id;
int roomId;
const char *name;
const char *roomName=NULL;
const char *devType;
const char *descr;
const char *location;
const AQH_ROOM *r=NULL;
id=(long unsigned int) AQH_Device_GetId(device);
roomId=(long unsigned int) AQH_Device_GetRoomId(device);
if (roomId>0)
r=AQH_Storage_GetRoomById(sto, roomId);
if (r)
roomName=AQH_Room_GetName(r);
name=AQH_Device_GetName(device);
devType=AQH_Device_GetDeviceType(device);
descr=AQH_Device_GetDescription(device);
location=AQH_Device_GetLocation(device);
GWEN_Buffer_AppendArgs(pageBuf,
"<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>"
"<td><a href=\"/devices/edit/%lu\">"
"<IMG src=\"/pics/edit.png\" width=32 height=32 align=left border=0></a></td>"
"</tr>",
name?name:"",
roomName?roomName:"",
devType?devType:"",
location?location:"",
descr?descr:"", id);
device=AQH_Device_List_Next(device);
}
}
GWEN_Buffer_AppendString(pageBuf, "</tbody>");
GWEN_Buffer_AppendArgs(pageBuf, "</table><a href=\"/devices/add\">%s</a><br>", I18N("Add Device"));
}

View File

@@ -1,23 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_STORAGE_U_DEVICES_H
#define AQHOME_STORAGE_U_DEVICES_H
#include "aqhome/http/urlhandler.h"
AQH_HTTP_URLHANDLER *AQH_DevicesHttpUrlHandler_new(AQH_SERVICE *sv);
#endif

View File

@@ -1,394 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "./u_login.h"
#include "aqhome/http/httpservice.h"
#include "aqhome/http/httpservice_http.h"
#include "aqhome/http/httpservice_conf.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint.h>
#include <gwenhywfar/mdigest.h>
#include <gwenhywfar/text.h>
#include <gwenhywfar/timestamp.h>
static int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
static int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
static int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
static int _loginUser(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
static int _verifyPass(AQH_USER *u, const char *userName, const char *password);
static AQH_SESSION *_generateSessionForUser(AQH_SERVICE *sv, AQH_USER *u);
static GWEN_BUFFER *_generateSessionUid(void);
static void _headerSetCookie(GWEN_DB_NODE *db, uint32_t flags, const char *cookieName, const char *cookieValue);
static GWEN_MSG *_createLoginResponseMsg(AQH_SERVICE *sv, const char *protocol, const char *sessionId, const char *newPage);
AQH_HTTP_URLHANDLER *AQH_LoginHttpUrlHandler_new(AQH_SERVICE *sv)
{
AQH_HTTP_URLHANDLER *uh;
uh=AQH_HttpUrlHandler_new(sv);
AQH_HttpUrlHandler_SetHandleFn(uh, _handleUrl);
return uh;
}
int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
{
const char *protocol;
const char *cmd;
GWEN_MSG *msgOut=NULL;
protocol=AQH_HttpRequest_GetProtocol(rq);
cmd=AQH_HttpRequest_GetCommand(rq);
if (cmd && *cmd) {
int rv;
if (strcasecmp(cmd, "GET")==0) {
rv=_handleGet(uh, rq);
if (rv<0) {
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
else if (strcasecmp(cmd, "POST")==0) {
rv=_handlePost(uh, rq);
if (rv<0) {
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
else {
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 405, "Method not allowed", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
}
return 0;
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "No command in request");
return GWEN_ERROR_INVALID;
}
}
int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
{
GWEN_BUFFER *pageBuf;
int rv;
GWEN_MSG *msgOut=NULL;
const char *protocol;
protocol=AQH_HttpRequest_GetProtocol(rq);
pageBuf=GWEN_Buffer_new(0, 256, 0, 1);
rv=AQH_HttpUrlHandler_AddContentHeaders(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
GWEN_Buffer_free(pageBuf);
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
rv=AQH_HttpService_AddFile(AQH_HttpUrlHandler_GetHttpService(uh), NULL, "login.html", pageBuf);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error reading file \"login.html\"");
GWEN_Buffer_free(pageBuf);
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
GWEN_Buffer_free(pageBuf);
return rv;
}
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
GWEN_Buffer_free(pageBuf);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
{
GWEN_DB_NODE *db;
int rv;
DBG_ERROR(NULL, "Login POST:");
db=AQH_HttpRequest_GetDbPostBody(rq);
GWEN_DB_Dump(db, 2);
rv=_loginUser(uh, rq);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return rv;
}
return 0;
}
int _loginUser(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
{
AQH_SERVICE *sv;
GWEN_MSG *msgOut=NULL;
const char *protocol;
GWEN_DB_NODE *db;
const char *userName;
const char *password;
AQH_USER *u;
AQH_SESSION *session;
int i;
int rv;
sv=AQH_HttpUrlHandler_GetHttpService(uh);
db=AQH_HttpRequest_GetDbPostBody(rq);
protocol=AQH_HttpRequest_GetProtocol(rq);
userName=GWEN_DB_GetCharValue(db, "username", 0, NULL);
password=GWEN_DB_GetCharValue(db, "password", 0, NULL);
if (!(userName && *userName && password && *password)) {
msgOut=AQH_HttpService_CreateResponseMsg(sv, 401, "Unauthorized", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
u=AQH_HttpService_GetUser(sv, userName);
if (u==NULL) {
DBG_INFO(NULL, "User \"%s\" not found", userName);
/* TODO: sleep */
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 401, "Unauthorized", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
i=AQH_User_GetState(u);
if (i==AQH_UserState_Suspended) {
DBG_INFO(NULL, "User \"%s\" suspended", userName);
/* TODO: sleep */
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 401, "Unauthorized", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
rv=_verifyPass(u, userName, password);
if (rv<0) {
if (rv==GWEN_ERROR_VERIFY)
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 401, "Unauthorized", protocol, "error");
else
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
/* TODO: sleep */
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
session=_generateSessionForUser(sv, u);
if (session==NULL) {
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
/* TODO: sleep */
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
DBG_ERROR(NULL, "Session generated");
AQH_User_SetTimestampLastLogin(u, AQH_Session_GetTimestampCreation(session));
rv=AQH_HttpService_WriteUser(sv, u);
if (rv<0) {
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
msgOut=_createLoginResponseMsg(sv, protocol, AQH_Session_GetUid(session), "/rooms/list");
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
return 0;
}
int _verifyPass(AQH_USER *u, const char *userName, const char *password)
{
GWEN_MDIGEST *md;
int rv;
const char *storedPasswordHash;
char buffer[70];
storedPasswordHash=AQH_User_GetHashedPassword(u);
if (!(storedPasswordHash && *storedPasswordHash)) {
DBG_ERROR(NULL, "No password hash stored with user \"%s\"", userName);
return GWEN_ERROR_INTERNAL;
}
md=GWEN_MDigest_Sha256_new();
rv=GWEN_MDigest_Begin(md);
if (rv<0) {
DBG_ERROR(NULL, "Error digesting given password [begin] (%d)", rv);
GWEN_MDigest_free(md);
return rv;
}
rv=GWEN_MDigest_Update(md, (const uint8_t*) password, strlen(password));
if (rv<0) {
DBG_ERROR(NULL, "Error digesting given password [update] (%d)", rv);
GWEN_MDigest_free(md);
return rv;
}
rv=GWEN_MDigest_End(md);
if (rv<0) {
DBG_ERROR(NULL, "Error digesting given password [end] (%d)", rv);
GWEN_MDigest_free(md);
return rv;
}
DBG_ERROR(NULL, "Digest needs %d bytes", (GWEN_MDigest_GetDigestSize(md)*2)+1);
if (NULL==GWEN_Text_ToHex((const char*) GWEN_MDigest_GetDigestPtr(md), GWEN_MDigest_GetDigestSize(md), buffer, sizeof(buffer)-1)) {
DBG_ERROR(NULL, "Buffer too small (need %d)", (GWEN_MDigest_GetDigestSize(md)*2)+1);
GWEN_MDigest_free(md);
return GWEN_ERROR_INTERNAL;
}
GWEN_MDigest_free(md);
if (strcasecmp(buffer, storedPasswordHash)!=0) {
DBG_ERROR(NULL, "Bad password for user \"%s\"", userName);
return GWEN_ERROR_VERIFY;
}
DBG_ERROR(NULL, "Valid password for user \"%s\"", userName);
return 0;
}
AQH_SESSION *_generateSessionForUser(AQH_SERVICE *sv, AQH_USER *u)
{
AQH_SESSION *session;
GWEN_BUFFER *buf;
GWEN_TIMESTAMP *ts;
int rv;
buf=_generateSessionUid();
if (buf==NULL) {
DBG_INFO(NULL, "here");
return NULL;
}
DBG_INFO(NULL, "New session id: [%s]", GWEN_Buffer_GetStart(buf));
session=AQH_Session_new();
AQH_Session_SetUid(session, GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
ts=GWEN_Timestamp_NowInLocalTime();
AQH_Session_SetTimestampCreation(session, ts);
AQH_Session_SetTimestampLastAccess(session, ts);
GWEN_Timestamp_free(ts);
AQH_Session_SetUserAlias(session, AQH_User_GetAlias(u));
AQH_Session_SetUser(session, u);
rv=AQH_HttpService_AddSession(sv, session);
if (rv<0) {
DBG_INFO(NULL, "Error adding session \"%s\" (%d)", AQH_Session_GetUid(session), rv);
AQH_Session_free(session);
return NULL;
}
return session;
}
GWEN_BUFFER *_generateSessionUid(void)
{
uint8_t binbuf[8];
GWEN_BUFFER *buf;
int rv;
rv=GWEN_SyncIo_Helper_PartiallyReadFile("/dev/urandom", binbuf, sizeof(binbuf));
if (rv<sizeof(binbuf)) {
DBG_ERROR(NULL, "Error reading from /dev/urandom: %d", rv);
return NULL;
}
buf=GWEN_Buffer_new(0, 20, 0, 1);
rv=GWEN_Text_ToHexBuffer((const char*) binbuf, rv, buf, 0, 0, 0);
if (rv<0) {
DBG_ERROR(NULL, "Error converting random bytes to hex (%d)", rv);
GWEN_Buffer_free(buf);
return NULL;
}
return buf;
}
GWEN_MSG *_createLoginResponseMsg(AQH_SERVICE *sv, const char *protocol, const char *sessionId, const char *newPage)
{
GWEN_BUFFER *buf;
GWEN_MSG *msg;
GWEN_DB_NODE *db;
buf=GWEN_Buffer_new(0, 256, 0, 1);
AQH_HttpService_AddStatusLine(sv, 303, "OK, redirecting to content", protocol, buf);
db=GWEN_DB_Group_new("header");
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "Keep-Alive");
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Type", "text/html; charset=utf-8");
_headerSetCookie(db, GWEN_DB_FLAGS_OVERWRITE_VARS, AQH_HTTP_REQUEST_SESSIONCOOKIE, sessionId);
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Location", newPage);
GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Length", 0);
AQH_HttpService_AddHeader(sv, db, buf);
GWEN_DB_Group_free(db);
msg=GWEN_Msg_fromBytes((const uint8_t*)GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetUsedBytes(buf));
GWEN_Buffer_free(buf);
return msg;
}
void _headerSetCookie(GWEN_DB_NODE *db, uint32_t flags, const char *cookieName, const char *cookieValue)
{
if (cookieName && cookieValue) {
GWEN_BUFFER *dbuf;
dbuf=GWEN_Buffer_new(0, 32, 0, 1);
GWEN_Buffer_AppendArgs(dbuf, "%s=%s", cookieName, cookieValue);
GWEN_DB_SetCharValue(db, flags, "Set-Cookie", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_free(dbuf);
}
}

Some files were not shown because too many files have changed in this diff Show More