blob: c3f1a50c9034f8de5c689738b397795561ea248c [file] [log] [blame]
xf.libdd93d52023-05-12 07:10:14 -07001/**
2 * @file regist.c
3 * @brief Implementation of regist.c.
4 *
5 * Copyright (C) 2022 Sanechips Technology Co., Ltd.
6 * @author
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. £¨±ØÑ¡£ºGPLv2 Licence£©
11 *
12 */
13
14
15/*******************************************************************************
16 * Include header files *
17 *******************************************************************************/
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21#include <pthread.h>
22#include <assert.h>
23#include <sys/ipc.h>
24
25#include "atreg_common.h"
26#include "message.h"
27#include "softap_log.h"
28#include "atreg_msg.h"
29
30
31/*******************************************************************************
32 * Macro definitions *
33 *******************************************************************************/
34
35
36/*******************************************************************************
37 * Type definitions *
38 *******************************************************************************/
39
40
41/*******************************************************************************
42 * Local variable definitions *
43 *******************************************************************************/
44/** ATÉÏÏÂÎijõʼ»¯±êÖ¾ */
45int atreg_ser_cxt_is_init = 0;
46int atreg_info_cxt_is_init = 0;
47
48/** loglevel³õʼ»¯±êÖ¾ */
49static int loglevel_is_init = 0;
50
51/** ¹«¹²²¿·Ö³õʼ»¯±êÖ¾ */
52static int common_is_init = 0;
53
54
55/*******************************************************************************
56 * Global variable definitions *
57 *******************************************************************************/
58
59
60/*******************************************************************************
61 * Local function declarations *
62 *******************************************************************************/
63
64
65/*******************************************************************************
66 * Local function implementations *
67 *******************************************************************************/
68/**
69 * @brief ³õʼ»¯ser ATÉÏÏÂÎÄ: atreg_ser_ctx
70 * @param ÎÞ
71 * @return ÎÞ
72 * @note ÎÞ
73 * @warning ÎÞ
74 */
75static void atreg_ser_init_proc()
76{
77 if(0 == atreg_ser_cxt_is_init) {
78 memset(&atreg_ser_ctx, 0, sizeof(atreg_ser_ctx));
79 memset(atreg_ser_dynamic_idpool, 0, sizeof(atreg_ser_dynamic_idpool));
80
81 INIT_LIST_HEAD(&atreg_ser_ctx.at_ser_list);
82 INIT_LIST_HEAD(&atreg_ser_ctx.at_ser_list_tmp);
83
84 pthread_mutex_init(&atreg_ser_ctx.at_ser_lock, NULL);
85 pthread_mutex_init(&atreg_ser_ctx.at_ser_lock_tmp, NULL);
86 pthread_mutex_init(&atreg_ser_ctx.at_ser_idpool_lock, NULL);
87
88 atreg_ser_cxt_is_init++;
89 slog(ATREG_PRINT, SLOG_NORMAL, "atreg_ser_init_proc init SUCCESS\n");
90 }
91
92 return;
93}
94
95
96/**
97 * @brief ³õʼ»¯info ATÉÏÏÂÎÄ: atreg_info_ctx
98 * @param ÎÞ
99 * @return ÎÞ
100 * @note ÎÞ
101 * @warning ÎÞ
102 */
103static void atreg_info_init_proc()
104{
105 if(0 == atreg_info_cxt_is_init) {
106 memset(&atreg_info_ctx, 0, sizeof(atreg_info_ctx));
107 memset(atreg_info_dynamic_idpool, 0, sizeof(atreg_info_dynamic_idpool));
108
109 INIT_LIST_HEAD(&atreg_info_ctx.at_info_list);
110 INIT_LIST_HEAD(&atreg_info_ctx.at_info_list_tmp);
111
112 pthread_mutex_init(&atreg_info_ctx.at_info_lock, NULL);
113 pthread_mutex_init(&atreg_info_ctx.at_info_lock_tmp, NULL);
114 pthread_mutex_init(&atreg_info_ctx.at_info_idpool_lock, NULL);
115
116 atreg_info_cxt_is_init++;
117 slog(ATREG_PRINT, SLOG_NORMAL, "atreg_info_init_proc init SUCCESS\n");
118 }
119
120 return;
121}
122
123
124/**
125 * @brief ´´½¨ÏûÏ¢´¦Àí×ÓÏß³Ì
126 * @param (in) ATÉÏÏÂÎÄ - common
127 * @return 0 - ³É¹¦
128 * ÆäËû - ʧ°Ü
129 * @note ÎÞ
130 * @warning ÎÞ
131 */
132static int atreg_create_msg_thread(struct atreg_common_context_t *patreg_common_ctx)
133{
134 return pthread_create(&(patreg_common_ctx->threadid), NULL, (void *)atreg_msg_thread_entry, (void *)patreg_common_ctx);
135}
136
137
138/**
139 * @brief ³õʼ»¯È«¾ÖATÉÏÏÂÎÄ: atreg_ser_ctx, atreg_info_ctx, atreg_common_ctx
140 * @param (in) atreg_type ×¢²áµÄATÀàÐÍ: 0-ser, 1-info
141 * @return 0 - ³É¹¦
142 * ÆäËû - ʧ°Ü
143 * @note ÎÞ
144 * @warning ÎÞ
145 */
146static int atreg_context_init(int atreg_type)
147{
148 if (0 == loglevel_is_init) {
149 loglevel_init();
150 loglevel_is_init++;
151 }
152
153 switch (atreg_type) {
154 case AT_REG_SER:
155 atreg_ser_init_proc();
156 break;
157
158 case AT_REG_INFO:
159 atreg_info_init_proc();
160 break;
161
162 default:
163 break;
164 }
165
166 if (0 == common_is_init) {
167 sem_init(&atreg_common_ctx.sem_id, 0, 0);
168 memset(&atreg_common_ctx.ts, 0, sizeof(struct timespec));
169
170 /* ÄÚ²¿¶¯Ì¬»ñȡԴģ¿éID£¬³õʼֵΪMODULE_ID_ATDYNAMIC_BASE */
171 atreg_common_ctx.modid = MODULE_ID_ATDYNAMIC_BASE;
172
173 while ((msgget(atreg_common_ctx.modid, IPC_CREAT|IPC_EXCL|0600)) == -1) {
174 atreg_common_ctx.modid++;
175
176 if (atreg_common_ctx.modid > MODULE_ID_ATDYNAMIC_END)
177 /* µ±at_ctx.modid´óÓÚMODULE_ID_ATDYNAMIC_ENDֵʱ£¬Ö÷¶¯¶ÏÑÔ */
178 softap_assert("atreg dynamic msg pipi not free timely!!!!!!!!!!!");
179 }
180
181 slog(ATREG_PRINT, SLOG_NORMAL, "atreg_context_init modid 0x%x\n", atreg_common_ctx.modid);
182
183 /* ´´½¨ÏûÏ¢´¦Àí×ÓÏß³Ì */
184 if (0 != atreg_create_msg_thread(&atreg_common_ctx))
185 return -1;
186
187 common_is_init++;
188 }
189
190 return 0;
191}
192
193
194/**
195 * @brief Ϊÿ¸ö×¢²áµÄser AT¹¹½¨ÊµÀý
196 * @param (in) at_cmd_prefix ×¢²áµÄser ATǰ׺
197 * @param (in) cb ×¢²áµÄ»Øµ÷º¯Êý
198 * @return ser ATʵÀý
199 * @note ÎÞ
200 * @warning ÎÞ
201 */
202static void *atreg_ser_construct_proc(char *at_cmd_prefix, ser_cb_proc cb)
203{
204 struct atreg_ser_instance_t *patreg_ser_instance = NULL;
205
206 patreg_ser_instance = (struct atreg_ser_instance_t *)malloc(sizeof(struct atreg_ser_instance_t));
207 if(NULL == patreg_ser_instance) {
208 return NULL;
209 }
210 memset(patreg_ser_instance, 0, sizeof(struct atreg_ser_instance_t));
211
212 strncpy(patreg_ser_instance->at_cmd_prefix, at_cmd_prefix, AT_CMD_PREFIX-1);
213 patreg_ser_instance->req_msg_id = -1;
214 patreg_ser_instance->rsp_msg_id = -1;
215 patreg_ser_instance->cb = cb;
216
217 return (void *)patreg_ser_instance;
218}
219
220
221/**
222 * @brief Ϊÿ¸ö×¢²áµÄinfo AT¹¹½¨ÊµÀý
223 * @param (in) at_cmd_prefix ×¢²áµÄinfo ATǰ׺
224 * @param (in) cb ×¢²áµÄ»Øµ÷º¯Êý
225 * @return info ATʵÀý
226 * @note ÎÞ
227 * @warning ÎÞ
228 */
229static void *atreg_info_construct_proc(char *at_cmd_prefix, ser_cb_proc cb)
230{
231 struct atreg_info_instance_t *patreg_info_instance = NULL;
232
233 patreg_info_instance = (struct atreg_info_instance_t *)malloc(sizeof(struct atreg_info_instance_t));
234 if(NULL == patreg_info_instance) {
235 return NULL;
236 }
237 memset(patreg_info_instance, 0, sizeof(struct atreg_info_instance_t));
238
239 strncpy(patreg_info_instance->at_cmd_prefix, at_cmd_prefix, AT_CMD_PREFIX-1);
240 patreg_info_instance->req_msg_id = -1;
241 patreg_info_instance->cb = cb;
242
243 return (void *)patreg_info_instance;
244}
245
246
247/**
248 * @brief Ϊÿ¸ö×¢²áµÄAT¹¹½¨ÊµÀý
249 * @param (in) at_cmd_prefix ×¢²áµÄATǰ׺
250 * @param (in) cb ×¢²áµÄ»Øµ÷º¯Êý
251 * @param (in) atreg_type ×¢²áµÄATÀàÐÍ: 0-ser, 1-info
252 * @return ATʵÀý
253 * @note ÎÞ
254 * @warning ÎÞ
255 */
256static void *atreg_construct(char *at_cmd_prefix, ser_cb_proc cb, int atreg_type)
257{
258 void* patreg = NULL;
259
260 switch (atreg_type) {
261 case AT_REG_SER:
262 patreg = atreg_ser_construct_proc(at_cmd_prefix, cb);
263 break;
264
265 case AT_REG_INFO:
266 patreg = atreg_info_construct_proc(at_cmd_prefix, cb);
267 break;
268
269 default:
270 break;
271 }
272
273 return patreg;
274}
275
276
277/**
278 * @brief Ϊÿ¸ö×¢²áµÄser AT¶¯Ì¬·ÖÅäreq_msg_idÓërsp_msg_id
279 * @param (out) patreg_ser_instance ×¢²áµÄser ATʵÀý
280 * @return ÎÞ
281 * @note ÎÞ
282 * @warning ÎÞ
283 */
284static void atreg_ser_allocation_proc(void* patreg_ser_instance)
285{
286 int i,j;
287 pthread_mutex_lock(&atreg_ser_ctx.at_ser_idpool_lock);
288 for (i =0; i < ATREG_SER_ID_MAX; i++) {
289 for (j = 7; j >= 0; j--) {
290 if (0 == atreg_ser_dynamic_idpool[i] & (1 << j)) {
291 ((struct atreg_ser_instance_t *)patreg_ser_instance)->req_msg_id = 8 * (i + 1) - (j + 1);
292 ((struct atreg_ser_instance_t *)patreg_ser_instance)->rsp_msg_id = 8 * (i + 1) - (j + 1) + 1;
293 atreg_ser_dynamic_idpool[i] = atreg_ser_dynamic_idpool[i] | (1 << j);
294 atreg_ser_dynamic_idpool[i] = atreg_ser_dynamic_idpool[i] | (1 << (j - 1));
295 pthread_mutex_unlock(&atreg_ser_ctx.at_ser_idpool_lock);
296
297 return;
298 }
299 }
300 }
301 pthread_mutex_unlock(&atreg_ser_ctx.at_ser_idpool_lock);
302
303 slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_ser_allocation_proc id pool is FULL\n");
304
305 return;
306}
307
308
309/**
310 * @brief Ϊÿ¸ö×¢²áµÄinfo AT¶¯Ì¬·ÖÅäreq_msg_id
311 * @param (out) patreg_info_instance ×¢²áµÄinfo ATʵÀý
312 * @return ÎÞ
313 * @note ÎÞ
314 * @warning ÎÞ
315 */
316static void atreg_info_allocation_proc(void* patreg_info_instance)
317{
318 int i,j;
319 pthread_mutex_lock(&atreg_info_ctx.at_info_idpool_lock);
320 for (i = 0; i < ATREG_INFO_ID_MAX; i++) {
321 for (j = 7; j >= 0; j--) {
322 if (0 == atreg_info_dynamic_idpool[i] & (1 << j)) {
323 ((struct atreg_info_instance_t *)patreg_info_instance)->req_msg_id = 8 * (i + 1) - (j + 1) + 512;
324 atreg_info_dynamic_idpool[i] = atreg_info_dynamic_idpool[i] | (1 << j);
325 pthread_mutex_unlock(&atreg_info_ctx.at_info_idpool_lock);
326
327 return;
328 }
329 }
330 }
331 pthread_mutex_unlock(&atreg_info_ctx.at_info_idpool_lock);
332
333 slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_info_allocation_proc id pool is FULL\n");
334
335 return;
336}
337
338
339/**
340 * @brief Ϊÿ¸ö×¢²áµÄAT¶¯Ì¬·ÖÅäreq_msg_idÓërsp_msg_id
341 * @param (in) atreg_type ×¢²áµÄATÀàÐÍ: 0-ser, 1-info
342 * @param (out) patreg_instance ×¢²áµÄATʵÀý
343 * @return ÎÞ
344 * @note ÎÞ
345 * @warning ÎÞ
346 */
347static void atreg_dynamic_id_allocation(void* patreg_instance, int atreg_type)
348{
349 switch (atreg_type) {
350 case AT_REG_SER:
351 atreg_ser_allocation_proc(patreg_instance);
352 break;
353
354 case AT_REG_INFO:
355 atreg_info_allocation_proc(patreg_instance);
356 break;
357
358 default:
359 break;
360 }
361}
362
363
364/*******************************************************************************
365 * Global function implementations *
366 *******************************************************************************/
367int reg_at_serv_func(char *at_cmd_prefix, ser_cb_proc cb)
368{
369 int send_ret = -1;
370 struct atreg_ser_instance_t *patreg_ser_instance = NULL;
371 struct atreg_msg_t *patreg_msgdata = NULL;
372
373 if (NULL == at_cmd_prefix || NULL == cb) {
374 slog(ATREG_PRINT, SLOG_ERR, "Err: register_serv_func para wrong, at_cmd_prefix or cb is NULL\n");
375 return -1;
376 }
377
378 /* at_context³õʼ»¯ */
379 if (-1 == atreg_context_init(AT_REG_SER))
380 return -1;
381
382 /* ¹¹½¨atʵÀý */
383 patreg_ser_instance = (struct atreg_ser_instance_t *)atreg_construct(at_cmd_prefix, cb, AT_REG_SER);
384 if (NULL == patreg_ser_instance) {
385 slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_construct AT %s fail!\n", at_cmd_prefix);
386 return -1;
387 }
388
389 /* ¶¯Ì¬·ÖÅäreq_msg_idÓërsp_msg_id */
390 atreg_dynamic_id_allocation((void *)patreg_ser_instance, AT_REG_SER);
391
392 /* »º´æatʵÀý */
393 pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock_tmp);
394 list_add_tail((struct list_head *)patreg_ser_instance, &atreg_ser_ctx.at_ser_list_tmp);
395 pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock_tmp);
396
397 /* ×¢²áatÖÁat_ctl */
398 patreg_msgdata = (struct atreg_msg_t *)malloc(sizeof(struct atreg_msg_t));
399 memset(patreg_msgdata, 0, sizeof(struct atreg_msg_t));
400 strncpy(patreg_msgdata->at_cmd_prefix, patreg_ser_instance->at_cmd_prefix, AT_CMD_PREFIX-1);
401 patreg_msgdata->req_msg_id = patreg_ser_instance->req_msg_id;
402 patreg_msgdata->rsp_msg_id = patreg_ser_instance->rsp_msg_id;
403 patreg_msgdata->type = AT_REG_SER;
404 patreg_msgdata->res = -1;
405
406 send_ret = ipc_send_message2(atreg_common_ctx.modid, MODULE_ID_AT_CTL, MSG_CMD_AT_REG_REQ, sizeof(struct atreg_msg_t), (unsigned char *)patreg_msgdata, 0);
407 if (0 != send_ret) {
408 slog(ATREG_PRINT, SLOG_ERR, "Err: register_serv_func ipc fail!\n");
409 return -1;
410 }
411
412 free(patreg_msgdata);
413
414 atreg_wait_rsp(MSG_CMD_AT_REG_REQ);
415
416 return 0;
417}
418
419
420int unreg_at_serv_func(char *at_cmd_prefix)
421{
422 int send_ret = -1;
423 struct atreg_ser_instance_t *patreg_ser_instance = NULL;
424 struct atreg_msg_t *patreg_msgdata = NULL;
425
426 if (NULL == at_cmd_prefix) {
427 slog(ATREG_PRINT, SLOG_ERR, "Err: unregister_serv_func para wrong, at_cmd_prefix=NULL!\n");
428 return -1;
429 }
430
431
432 patreg_ser_instance = (struct atreg_ser_instance_t *)atreg_search_instance_by_prefix(at_cmd_prefix, AT_REG_SER);
433 if (NULL == patreg_ser_instance) {
434 slog(ATREG_PRINT, SLOG_ERR, "Err: unreg_at_serv_func AT %s not regist yet\n", at_cmd_prefix);
435 return -1;
436 }
437
438 patreg_msgdata = (struct atreg_msg_t *)malloc(sizeof(struct atreg_msg_t));
439 memset(patreg_msgdata, 0, sizeof(struct atreg_msg_t));
440 strncpy(patreg_msgdata->at_cmd_prefix, patreg_ser_instance->at_cmd_prefix, AT_CMD_PREFIX-1);
441 patreg_msgdata->req_msg_id = patreg_ser_instance->req_msg_id;
442 patreg_msgdata->rsp_msg_id = patreg_ser_instance->rsp_msg_id;
443 patreg_msgdata->type = AT_REG_SER;
444 patreg_msgdata->res = -1;
445
446 send_ret = ipc_send_message2(atreg_common_ctx.modid, MODULE_ID_AT_CTL, MSG_CMD_AT_UNREG_REQ, sizeof(struct atreg_msg_t), (unsigned char *)patreg_msgdata, 0);
447 if (0 != send_ret) {
448 slog(ATREG_PRINT, SLOG_ERR, "Err: unregister_serv_func ipc fail!\n");
449 return -1;
450 }
451
452 free(patreg_msgdata);
453
454 atreg_wait_rsp(MSG_CMD_AT_UNREG_REQ);
455
456 return 0;
457}
458
459
460int reg_at_info_func(char *at_cmd_prefix, info_cb_proc cb)
461{
462 int send_ret = -1;
463 struct atreg_info_instance_t *patreg_info_instance = NULL;
464 struct atreg_msg_t *patreg_msgdata = NULL;
465
466 if (NULL == at_cmd_prefix || NULL == cb) {
467 slog(ATREG_PRINT, SLOG_ERR, "Err: register_info_func para wrong, at_cmd_prefix or cb is NULL\n");
468 return -1;
469 }
470
471 /* at_context³õʼ»¯ */
472 if (-1 == atreg_context_init(AT_REG_INFO))
473 return -1;
474
475 /* ¹¹½¨atʵÀý */
476 patreg_info_instance = (struct atreg_info_instance_t *)atreg_construct(at_cmd_prefix, cb, AT_REG_INFO);
477 if (NULL == patreg_info_instance) {
478 slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_construct AT %s fail!\n", at_cmd_prefix);
479 return -1;
480 }
481
482 /* ¶¯Ì¬·ÖÅäreq_msg_id */
483 atreg_dynamic_id_allocation((void *)patreg_info_instance, AT_REG_INFO);
484
485 /* »º´æatʵÀý */
486 pthread_mutex_lock(&atreg_info_ctx.at_info_lock_tmp);
487 list_add_tail((struct list_head *)patreg_info_instance, &atreg_info_ctx.at_info_list_tmp);
488 pthread_mutex_unlock(&atreg_info_ctx.at_info_lock_tmp);
489
490 /* ×¢²áatÖÁat_ctl */
491 patreg_msgdata = (struct atreg_msg_t *)malloc(sizeof(struct atreg_msg_t));
492 memset(patreg_msgdata, 0, sizeof(struct atreg_msg_t));
493 strncpy(patreg_msgdata->at_cmd_prefix, patreg_info_instance->at_cmd_prefix, AT_CMD_PREFIX-1);
494 patreg_msgdata->req_msg_id = patreg_info_instance->req_msg_id;
495 patreg_msgdata->rsp_msg_id = -1;
496 patreg_msgdata->type = AT_REG_INFO;
497 patreg_msgdata->res = -1;
498
499 send_ret = ipc_send_message2(atreg_common_ctx.modid, MODULE_ID_AT_CTL, MSG_CMD_AT_REG_REQ, sizeof(struct atreg_msg_t), (unsigned char *)patreg_msgdata, 0);
500 if (0 != send_ret) {
501 slog(ATREG_PRINT, SLOG_ERR, "Err: register_info_func ipc fail!\n");
502 return -1;
503 }
504
505 free(patreg_msgdata);
506
507 atreg_wait_rsp(MSG_CMD_AT_REG_REQ);
508
509 return 0;
510}
511
512
513int unreg_at_info_func(char *at_cmd_prefix)
514{
515 int send_ret = -1;
516 struct atreg_info_instance_t *patreg_info_instance = NULL;
517 struct atreg_msg_t *patreg_msgdata = NULL;
518
519 if (NULL == at_cmd_prefix) {
520 slog(ATREG_PRINT, SLOG_ERR, "Err: unregister_info_func para wrong, at_cmd_prefix=NULL!\n");
521 return -1;
522 }
523
524 patreg_info_instance = (struct atreg_info_instance_t *)atreg_search_instance_by_prefix(at_cmd_prefix, AT_REG_INFO);
525 if (NULL == patreg_info_instance) {
526 slog(ATREG_PRINT, SLOG_ERR, "Err: unreg_at_info_func AT %s not regist yet\n", at_cmd_prefix);
527 return -1;
528 }
529
530 patreg_msgdata = (struct atreg_msg_t *)malloc(sizeof(struct atreg_msg_t));
531 memset(patreg_msgdata, 0, sizeof(struct atreg_msg_t));
532 strncpy(patreg_msgdata->at_cmd_prefix, patreg_info_instance->at_cmd_prefix, AT_CMD_PREFIX-1);
533 patreg_msgdata->req_msg_id = patreg_info_instance->req_msg_id;
534 patreg_msgdata->rsp_msg_id = -1;
535 patreg_msgdata->type = AT_REG_INFO;
536 patreg_msgdata->res = -1;
537
538 send_ret = ipc_send_message2(atreg_common_ctx.modid, MODULE_ID_AT_CTL, MSG_CMD_AT_UNREG_REQ, sizeof(struct atreg_msg_t), (unsigned char *)patreg_msgdata, 0);
539 if (0 != send_ret) {
540 slog(ATREG_PRINT, SLOG_ERR, "Err: unregister_info_func ipc fail!\n");
541 return -1;
542 }
543
544 free(patreg_msgdata);
545
546 atreg_wait_rsp(MSG_CMD_AT_UNREG_REQ);
547
548 return 0;
549}
550