InPlay API
hal_ipmac.h
1 #include "in_config.h"
13 #include <stdint.h>
14 #if !CFG_NO_OS
15 #include "cmsis_os.h"
16 #endif
17 #include "./hal/hal_power.h"
18 #include "ipmac.h"
19 
29 #ifndef HAL_IPMAC_H
30 #define HAL_IPMAC_H
31 
32 #if !CFG_NO_OS
33 #define SEMA_NUM (2*(CFG_IPMAC_MAX_SLV_NUM + 1 + 1))
34 #define BC_SEMA 0
35 #define BCA_SEMA 1
36 #define PDU_SEMA 2
37 #endif
38 
39 #define BC_INT_BUF_LEN 7 //For hopping
40 
41 enum ipmac_queue_prio {
42  IPMAC_HIGH_PRI_QID = 0,
43  IPMAC_LOW_PRI_QID = 1,
44 };
45 
49 typedef struct {
50  int mode;
51  int slv_num;
52  int slot_time;
53  int phy_rate;
54  uint32_t access_addr;
55  int irq_prio;
56  int single_rx;
57  int same_len;
58  uint8_t hopping_en;
59  uint8_t rssi_scan_en;
60  uint8_t join_en;
61 } ipmac_init_t;
62 
66 typedef struct {
67  void (*prev_irq_cb)(void* arg, uint32_t status);
68  void *prev_irq_arg;
69  void (*post_irq_cb)(void* arg, uint32_t status);
70  void *post_irq_arg;
71  void (*rx_cb)(void *arg, int slv_id, int llid, uint8_t *buffer, uint16_t buffer_len);
72  void *rx_arg;
73  void (*tx_cb)(void* arg, int slv_id, int type, int order);
74  void *tx_arg;
75  void (*status_cb)(uint32_t status,uint8_t slv_id);
77 
80 typedef struct {
81  void (*prev_irq_cb)(void* arg, uint32_t status);
82  void *prev_irq_arg;
83  void (*post_irq_cb)(void* arg, uint32_t status);
84  void *post_irq_arg;
85  void (*rx_cb)(void *arg, int type, int llid, uint8_t *buffer, uint16_t buffer_len);
86  void *rx_arg;
87  void (*tx_cb)(void* arg, int order);
88  void *tx_arg;
89  void (*status_cb)(uint32_t status);
90  void (*sync_status_cb)(void *arg, uint32_t status);
92 
95 typedef struct {
96  int type;
97  int slv_id;
98  uint8_t *buf;
99  uint16_t buf_len;
100  uint32_t tmo;
101  void *arg;
102  void (*callback)(void *arg, int type, int slv_id, int status);
104 
107 typedef struct {
108  int type;
109  int slv_id;
110  uint8_t *buf;
111  uint16_t buf_len;
112  int prio;
114 
117 typedef struct {
118  uint8_t *buf;
119  uint16_t buf_len;
120  uint32_t tmo;
121  void *arg;
122  void (*callback)(void *arg, int status);
124 
127 typedef struct {
128  uint8_t *buf;
129  uint16_t buf_len;
130  uint32_t prio;
132 
135 typedef struct {
137  uint16_t item_num;
138  uint16_t pdu_sz;
139  uint8_t max_retry;
140 } ipmac_queue_t;
141 
144 typedef struct {
145  uint8_t *sync;
146  int sync_len;
147  uint8_t *sync_loss;
150 
151 
154 typedef struct {
155  int slv_id;
156  int type;
157  uint32_t tmo;
158  uint32_t access_addr;
159  ipmac_offset_param_t offset;
160  void *arg;
161  void (*callback)(void *arg, int type, int slv_id, int status);
163 
166 typedef struct {
167  int slot_time;
168  int phy_rate;
169  int slv_num;
170  uint32_t access_addr;
171  ipmac_offset_param_t offset;
173 
176 typedef struct {
177  int slot_time;
178  int phy_rate;
179  int slv_id;
180  uint32_t access_addr;
181  ipmac_offset_param_t offset;
183 
184 typedef struct {
185  pkt_len_t tx_pdu_len[CFG_IPMAC_MAX_SLV_NUM];
186  pkt_len_t resp_pdu_len[CFG_IPMAC_MAX_SLV_NUM];
187 
188 #if !CFG_NO_OS
189  osSemaphoreId semaphore[SEMA_NUM];
190  uint32_t sma[2*SEMA_NUM];
191  uint8_t wait[SEMA_NUM];
192 #endif
193  void *tx_bc_arg;
194  void (*tx_bc_cb)(void *arg, int type, int slv_id, int status);
195  void *tx_bca_arg;
196  void (*tx_bca_cb)(void *arg, int type, int slv_id, int status);
197  void *tx_pdu_arg[CFG_IPMAC_MAX_SLV_NUM];
198  void (*tx_pdu_cb[CFG_IPMAC_MAX_SLV_NUM])(void *arg, int type, int slv_id, int status);
199 
200  char queue_en[CFG_IPMAC_MAX_SLV_NUM];
201  char low_prio_en[CFG_IPMAC_MAX_SLV_NUM];
202  uint8_t tx_e_cnt[CFG_IPMAC_MAX_SLV_NUM];
203  uint8_t tx_o_cnt[CFG_IPMAC_MAX_SLV_NUM];
204  uint8_t tx_e_prio[CFG_IPMAC_MAX_SLV_NUM];
205  uint8_t tx_o_prio[CFG_IPMAC_MAX_SLV_NUM];
206  uint8_t tx_max_retry[CFG_IPMAC_MAX_SLV_NUM];//for low priority
207  void *mst_tx_arg;
208  void (*mst_tx_cb)(void* arg, int type, int order, int slv_id);
209  void *mst_rx_arg;
210  void (*mst_rx_cb)(void *arg, int slv_id, int llid, uint8_t *buffer, uint16_t buffer_len);
211  void (*mst_status_cb)(uint32_t status,uint8_t slv_id);
212  #if !IPMAC_USE_SN
213  //uint8_t state[CFG_IPMAC_MAX_SLV_NUM];
214  uint8_t tx_bc_order;
215  uint8_t tx_bca_order;
216  uint8_t tx_pdu_order[CFG_IPMAC_MAX_SLV_NUM];
217  uint8_t rx_pdu_order[CFG_IPMAC_MAX_SLV_NUM];
218  //uint8_t extra_order;
219  #endif
220  uint8_t tx_bc_e_req;
221  uint8_t tx_bc_o_req;
222  uint8_t tx_bca_e_req;
223  uint8_t tx_bca_o_req;
224  uint8_t tx_pdu_e_req[CFG_IPMAC_MAX_SLV_NUM];
225  uint8_t tx_pdu_o_req[CFG_IPMAC_MAX_SLV_NUM];
226  uint8_t irq_rx_slv_id;
227 
228  uint8_t *bc_app_buf;
229  pkt_len_t bc_app_buf_max_len;
230  pkt_len_t bc_app_buf_len;
231  int bc_cont_tx;
232 #if BC_INT_BUF_LEN
233  pkt_len_t bc_int_buf_len;
234  uint8_t bc_int_buf[BC_INT_BUF_LEN];
235 #endif
236 } ipmac_mst_dev_t;
237 typedef struct {
238  pkt_len_t tx_pdu_len;
239  pkt_len_t resp_pdu_len;
240 
241 #if !CFG_NO_OS
242  osSemaphoreId semaphore[2];
243  uint32_t sma[2*2];
244  uint8_t wait[2];
245 #endif
246  void *tx_arg;
247  void (*tx_cb)(void *arg, int status);
248  char queue_en;
249  char low_prio_en;
250  uint16_t tx_e_cnt;
251  uint16_t tx_o_cnt;
252  uint8_t tx_e_prio;
253  uint8_t tx_o_prio;
254  uint8_t tx_max_retry;//for low priority
255  void *slv_rx_arg;
256  void (*slv_rx_cb)(void *arg, int type, int llid, uint8_t *buffer, uint16_t buffer_len);
257  void *slv_tx_arg;
258  void (*slv_tx_cb)(void*arg, int order);
259  void (*slv_status_cb)(uint32_t status);
260  void (*slv_sync_status_cb)(void *arg, uint32_t status);
261  #if !IPMAC_USE_SN
262  uint8_t resp_tx_order;
263  uint8_t extra_tx_order;
264  uint8_t bc_order;
265  uint8_t bca_order;
266  //uint8_t extra_pdu_order;
267  #endif
268  uint8_t resp_tx_e_req;
269  uint8_t resp_tx_o_req;
270  uint8_t extra_tx_e_req;
271  uint8_t extra_tx_o_req;
272  uint8_t rx_pdu_order;
273 } ipmac_slv_dev_t;
274 typedef struct {
275 #if !CFG_NO_OS
276  osMutexId mutex;
277 #endif
278  int mode;
279  int slv_num;
280  int slot_time;
281  int phy_rate;
282  uint32_t access_addr;
283 
284  int used;
285  int slv_id;
286  int sync_status;
287  int16_t inst_rssi[CFG_IPMAC_MAX_SLV_NUM];
288  uint16_t frame_duration;
289  uint16_t slv_frame_oft[CFG_IPMAC_MAX_SLV_NUM];
290  uint16_t resp_frame_oft;
291 
292  int bcn_margin;
293  int slv_margin;
294  uint8_t single_rx;
295  uint8_t same_len;
296  uint8_t hopping_en;
297  uint8_t sync_tbl[32];
298  int sync_len;
299  uint8_t sync_loss_tbl[32];
300  int sync_loss_len;
301  uint8_t rssi_scan_en;
302  uint8_t join_en;
303  uint8_t join_start;
304 
305  void (*prev_irq_cb)(void* arg, uint32_t status);
306  void *prev_irq_arg;
307  void (*post_irq_cb)(void* arg, uint32_t status);
308  void *post_irq_arg;
309 
310 
311  pkt_len_t bc_len;
312  pkt_len_t bca_len;
313  ipmac_mst_dev_t mst;
314  ipmac_slv_dev_t slv;
315  ipmac_mem_t mm;
316  #if CFG_PM_EN
317  int power_state;
318  struct pm_module pmd;
319  #endif
320 } ipmac_dev_t;
321 
322 typedef struct {
323  uint8_t ctrl_pdu_type;
324  uint8_t payload[];
325 } ipmac_ctrl_pdu_t;
326 /*
327  * APIs
328  ****************************************************************************************
329  */
341 ipmac_dev_t* hal_ipmac_open(ipmac_init_t* para);
342 
352 void hal_ipmac_close(ipmac_dev_t* pd);
353 
364 int hal_ipmac_mst_cfg(ipmac_dev_t* pd, ipmac_offset_param_t *offset);
365 
377 int hal_ipmac_slv_cfg(ipmac_dev_t* pd, int slv_id, ipmac_offset_param_t *offset);
378 
391 int hal_ipmac_set_freq_table(ipmac_dev_t* pd, ipmac_freq_tab_t* tab);
392 
402 int hal_ipmac_mst_start(ipmac_dev_t* pd);
403 
414 int hal_ipmac_slv_start(ipmac_dev_t* pd);
415 
427 int hal_ipmac_mst_tx(ipmac_dev_t* pd, ipmac_mst_tx_t *para);
428 
440 int hal_ipmac_slv_tx(ipmac_dev_t* pd, ipmac_slv_tx_t* para);
441 
442 
443 int hal_ipmac_slv_prio_tx(ipmac_dev_t* pd, ipmac_slv_prio_tx_t* para);
444 
456 int hal_ipmac_mst_udpate_remote_offset(ipmac_dev_t* pd, ipmac_update_remote_t* update);
457 
468 int hal_ipmac_mst_stop(ipmac_dev_t* pd);
469 
479 int hal_ipmac_mst_set_cb(ipmac_dev_t* pd, ipmac_mst_cb_t* cb);
480 
489 int hal_ipmac_slv_set_cb(ipmac_dev_t* pd, ipmac_slv_cb_t* cb);
490 
501 int hal_ipmac_slv_stop(ipmac_dev_t* pd);
502 
514 int hal_ipmac_slv_en_queue(ipmac_dev_t* pd, ipmac_queue_t *para);
515 
526 int hal_ipmac_slv_dis_queue(ipmac_dev_t* pd);
527 
540 int hal_ipmac_mst_en_queue(ipmac_dev_t* pd, int slv_id, ipmac_queue_t *para);
541 
553 int hal_ipmac_mst_dis_queue(ipmac_dev_t* pd, int slv_id);
554 
555 
567 int hal_ipmac_mst_ota_tx(ipmac_dev_t* pd, ipmac_mst_tx_t *para);
568 
579 int hal_ipmac_bc_int_set(ipmac_dev_t* pd, uint8_t *data, uint16_t len);
580 
591 int hal_ipmac_set_bc_buf(ipmac_dev_t* pd, uint8_t *buf, uint16_t max_len);
592 
603 int hal_ipmac_mst_bc_cont_tx(ipmac_dev_t* pd, uint8_t *buffer, uint16_t buffer_len);
604 
615 int hal_ipmac_slv_status(ipmac_dev_t* pd);
616 
627 uint32_t hal_ipmac_frame_time(ipmac_dev_t* pd);
628 
637 int16_t get_rssi(void);
638 int ipmac_get_rssi(int id);
639 
654 uint32_t hal_ipmac_convert_sf_timestamp(ipmac_dev_t* pd, uint32_t sf_reg);
655 
667 int hal_ipmac_enable_intr(ipmac_dev_t* pd, uint32_t intr_src);
668 
680 int hal_ipmac_disable_intr(ipmac_dev_t* pd, uint32_t intr_src);
681 
694 int hal_ipmac_set_sync(ipmac_dev_t* pd, uint8_t addr_idx, uint32_t address);
707 int hal_ipmac_set_resp_sync(ipmac_dev_t* pd, uint8_t addr_idx, uint32_t address);
720 int hal_ipmac_sync_sel(ipmac_dev_t* pd, uint8_t addr_idx, uint8_t sf_idx);
721 
734 int hal_ipmac_resp_sync_sel(ipmac_dev_t* pd, uint8_t addr_idx, uint8_t sf_idx);
735 
746 int hal_ipmac_sync_sel_clear(ipmac_dev_t* pd);
747 
758 int hal_ipmac_resp_sync_sel_clear(ipmac_dev_t* pd);
759 
760 
762 
763 #endif
764 
int slv_id
Slave id, 1 to 127.
Definition: hal_ipmac.h:97
int type
Packet type, enum ipmac_packet_type.
Definition: hal_ipmac.h:108
int prio
Queue priority, enum ipmac_queue_prio.
Definition: hal_ipmac.h:112
uint32_t access_addr
Access address.
Definition: hal_ipmac.h:158
int same_len
Enable same length, the pdu length of master to all slave is same. 1:enable, 0:disable.
Definition: hal_ipmac.h:57
ipmac_offset_param_t offset
offset parameter
Definition: hal_ipmac.h:159
uint16_t buf_len
Buffer length.
Definition: hal_ipmac.h:129
void * post_irq_arg
IPMAC interrupt callback arguments.
Definition: hal_ipmac.h:70
int phy_rate
Phy rate. enum ipmac_phy_rate.
Definition: hal_ipmac.h:53
int hal_ipmac_resp_sync_sel(ipmac_dev_t *pd, uint8_t addr_idx, uint8_t sf_idx)
Select the response SYNC word for the superframe.
int slv_id
Slave id.
Definition: hal_ipmac.h:155
int hal_ipmac_set_sync(ipmac_dev_t *pd, uint8_t addr_idx, uint32_t address)
set SYNC word, 4 different SYNC words can be configured.
uint16_t item_num
Item number in one queue.
Definition: hal_ipmac.h:137
void hal_ipmac_close(ipmac_dev_t *pd)
Close HAL IPMAC driver.
int slv_id
Slave id, 1 to 127.
Definition: hal_ipmac.h:109
uint32_t prio
Queue priority,.
Definition: hal_ipmac.h:130
int hal_ipmac_mst_ota_tx(ipmac_dev_t *pd, ipmac_mst_tx_t *para)
Master send OTA data.
int sync_loss_len
Sync loss table length, max length is 32.
Definition: hal_ipmac.h:148
int hal_ipmac_mst_udpate_remote_offset(ipmac_dev_t *pd, ipmac_update_remote_t *update)
Master udpate slave offset parameter.
ipmac_offset_param_t offset
offset parameter
Definition: hal_ipmac.h:181
int hal_ipmac_set_freq_table(ipmac_dev_t *pd, ipmac_freq_tab_t *tab)
Set frequency table.
int slv_id
Slave id.
Definition: hal_ipmac.h:179
ipmac_offset_param_t offset
offset parameter
Definition: hal_ipmac.h:171
uint8_t hopping_en
enable hopping.
Definition: hal_ipmac.h:58
int hal_ipmac_set_bc_buf(ipmac_dev_t *pd, uint8_t *buf, uint16_t max_len)
set bc buffer and maximum length
int hal_ipmac_slv_start(ipmac_dev_t *pd)
Start slave device.
uint8_t * buf
Data buffer.
Definition: hal_ipmac.h:98
Initialization parameters for ipmac.
Definition: hal_ipmac.h:49
int hal_ipmac_mst_bc_cont_tx(ipmac_dev_t *pd, uint8_t *buffer, uint16_t buffer_len)
update broadcast pdu buffer, and tx in every frame. need firstly call
uint32_t tmo
Timeout,unit is ms. osWaitForever:wait forever timeout value, 0:don&#39;t wait, return immediately...
Definition: hal_ipmac.h:100
int irq_prio
IPMAC interrupt priority,.
Definition: hal_ipmac.h:55
int type
Packet type, enum ipmac_packet_type.
Definition: hal_ipmac.h:96
Slave TX parameter.
Definition: hal_ipmac.h:117
int slot_time
Slot time, unit is us. Only 16 and 64 is available. enum ipmac_slot_time.
Definition: hal_ipmac.h:52
Slave callback parameter.
Definition: hal_ipmac.h:80
uint8_t * sync
Sync table. When device in sync status, use this table.
Definition: hal_ipmac.h:145
int type
enum ipmac_packet_type.
Definition: hal_ipmac.h:156
void * prev_irq_arg
IPMAC interrupt callback arguments.
Definition: hal_ipmac.h:68
int hal_ipmac_set_resp_sync(ipmac_dev_t *pd, uint8_t addr_idx, uint32_t address)
set response SYNC word
void * tx_arg
TX callback arguments.
Definition: hal_ipmac.h:74
void * rx_arg
RX callback arguments.
Definition: hal_ipmac.h:72
int slv_num
Slave number. Only available in master mode.
Definition: hal_ipmac.h:51
uint32_t tmo
Time out.
Definition: hal_ipmac.h:157
int hal_ipmac_slv_set_cb(ipmac_dev_t *pd, ipmac_slv_cb_t *cb)
Set slave callback.
uint32_t hal_ipmac_frame_time(ipmac_dev_t *pd)
Get the real time of the superframe.
int hal_ipmac_mst_set_cb(ipmac_dev_t *pd, ipmac_mst_cb_t *cb)
Set master callback.
void * arg
Argument passed to callback function when callback is called.
Definition: hal_ipmac.h:121
int hal_ipmac_mst_en_queue(ipmac_dev_t *pd, int slv_id, ipmac_queue_t *para)
Master enable queue.
void * tx_arg
TX callback arguments.
Definition: hal_ipmac.h:88
Master TX parameter.
Definition: hal_ipmac.h:95
ipmac_dev_t * hal_ipmac_open(ipmac_init_t *para)
Open HAL IPMAC driver.
int slv_num
Slave number, 1 to 127.
Definition: hal_ipmac.h:169
void * post_irq_arg
IPMAC interrupt callback arguments.
Definition: hal_ipmac.h:84
int slot_time
Slot time, enum ipmac_slot_time.
Definition: hal_ipmac.h:177
int hal_ipmac_mst_tx(ipmac_dev_t *pd, ipmac_mst_tx_t *para)
Send packet from master device.
int16_t get_rssi(void)
Get RSSI.
int phy_rate
Phy rate, enum ipmac_phy_rate.
Definition: hal_ipmac.h:178
int hal_ipmac_bc_int_set(ipmac_dev_t *pd, uint8_t *data, uint16_t len)
udpate internal buffer of broadcast pdu, normally, is using to hopping application.
void * arg
Argument passed to callback function when callback is called.
Definition: hal_ipmac.h:101
uint8_t join_en
enable join.
Definition: hal_ipmac.h:60
uint16_t buf_len
Buffer length.
Definition: hal_ipmac.h:99
uint16_t pdu_sz
Pdu size for one item.
Definition: hal_ipmac.h:138
int en_low_prio
Enable low priority queue. 1:enable, 0:disable.
Definition: hal_ipmac.h:136
Slave update configration parameter.
Definition: hal_ipmac.h:176
uint32_t access_addr
Access address.
Definition: hal_ipmac.h:180
uint32_t access_addr
Access address. Master and slave should use same access address. Don&#39;t use 0x0 or 0xFFFFFFFF...
Definition: hal_ipmac.h:54
int hal_ipmac_enable_intr(ipmac_dev_t *pd, uint32_t intr_src)
Enable interrupt.
int hal_ipmac_slv_status(ipmac_dev_t *pd)
Get current status of the slave.
void * rx_arg
RX callback arguments.
Definition: hal_ipmac.h:86
int sync_len
Sync table length, max length is 32.
Definition: hal_ipmac.h:146
int hal_ipmac_sync_sel(ipmac_dev_t *pd, uint8_t addr_idx, uint8_t sf_idx)
Select the SYNC word for the superframe.
uint8_t * buf
Data buffer.
Definition: hal_ipmac.h:118
int hal_ipmac_slv_en_queue(ipmac_dev_t *pd, ipmac_queue_t *para)
Slave enable queue.
Master callback parameter.
Definition: hal_ipmac.h:66
int hal_ipmac_resp_sync_sel_clear(ipmac_dev_t *pd)
The default response SYNC word is used for all superframes.
void * prev_irq_arg
IPMAC interrupt callback arguments.
Definition: hal_ipmac.h:82
uint32_t tmo
Timeout,unit is ms. osWaitForever:wait forever timeout value, 0:don&#39;t wait, return immediately...
Definition: hal_ipmac.h:120
int hal_ipmac_slv_stop(ipmac_dev_t *pd)
Stop slave device.
Master update configration parameter.
Definition: hal_ipmac.h:166
int hal_ipmac_slv_dis_queue(ipmac_dev_t *pd)
Slave disable queue.
Update remote deivce parameter.
Definition: hal_ipmac.h:154
int mode
Master or slave, enum ipmac_mode.
Definition: hal_ipmac.h:50
int hal_ipmac_mst_cfg(ipmac_dev_t *pd, ipmac_offset_param_t *offset)
Config master device.
uint8_t max_retry
Max retry number.
Definition: hal_ipmac.h:139
int hal_ipmac_mst_stop(ipmac_dev_t *pd)
Stop master device.
int hal_ipmac_slv_cfg(ipmac_dev_t *pd, int slv_id, ipmac_offset_param_t *offset)
Config slave device.
uint8_t * sync_loss
Sync loss table. When device in sync loss status, use this table.
Definition: hal_ipmac.h:147
Frequence table parameter.
Definition: hal_ipmac.h:144
int hal_ipmac_disable_intr(ipmac_dev_t *pd, uint32_t intr_src)
Disable Interrupt.
int hal_ipmac_mst_dis_queue(ipmac_dev_t *pd, int slv_id)
Master disable queue.
uint32_t hal_ipmac_convert_sf_timestamp(ipmac_dev_t *pd, uint32_t sf_reg)
Convert the super frame counter into time. Before successfully using this API, you should do the foll...
uint8_t * buf
Data buffer.
Definition: hal_ipmac.h:110
int hal_ipmac_mst_start(ipmac_dev_t *pd)
Start master device.
int hal_ipmac_sync_sel_clear(ipmac_dev_t *pd)
The default SYNC word is used for all superframes.
Slave priority TX parameter.
Definition: hal_ipmac.h:127
Queue configuration parameter.
Definition: hal_ipmac.h:135
uint16_t buf_len
Buffer length.
Definition: hal_ipmac.h:111
uint8_t * buf
Data buffer.
Definition: hal_ipmac.h:128
int phy_rate
Phy rate, enum ipmac_phy_rate.
Definition: hal_ipmac.h:168
int single_rx
Enable single rx. 1:enable, 0:disable.
Definition: hal_ipmac.h:56
int hal_ipmac_slv_tx(ipmac_dev_t *pd, ipmac_slv_tx_t *para)
Send packet from slave device.
uint8_t rssi_scan_en
enable rssi scan.
Definition: hal_ipmac.h:59
uint16_t buf_len
Buffer length.
Definition: hal_ipmac.h:119
int slot_time
Slot time, enum ipmac_slot_time.
Definition: hal_ipmac.h:167
uint32_t access_addr
Access address.
Definition: hal_ipmac.h:170
Master priority TX parameter.
Definition: hal_ipmac.h:107