Code Analysis of Carrier communication module

Source: Internet
Author: User
struct plc_state
{
Uint8 cur_state;
Uint8 next_state;


Uint8 (*action) (uint8 init, void *args);//How does this structure work?

};
void plc_machine_opt (void *args)
{
struct Plc_state *pstate = plc_state.pstate;//The key is to see who changed the Plc_state.pstate, found who changed it, is the upstream data to get through.
Uint8 Init;


init = Plc_state.init;
if (init) plc_state.wait_t=0;
Plc_state.init = 0;
if (NULL! = pstate)
{
Pstate->action (init, args); Call the code where he called again ....
}
}

After searching in the code we can clearly see that the void Chg_state (Uint8 cur_state) changed the value of the PLC _state.pstate. The part of the change is shown in the red code below.
void Chg_state (Uint8 cur_state)
{
Uint8 i;
Static Uint8 Last_state=invalid;

plc_state.wait_t = 0;
Plc_state.init=1;
for (i = 0; i < PLC_SLOT_SZ; i++)
{
if (plc_state_slot[i].cur_state = = cur_state)
{
Plc_state.pstate = (struct plc_state *) &plc_state_slot[i];
Break
}
}
if (i >= PLC_SLOT_SZ)
{
Plc_state.pstate = (struct plc_state *) &plc_state_slot[0];
}


if (last_state! = plc_state.pstate->cur_state)
{
plc_state.trycnt = 0;
}
Last_state = plc_state.pstate->cur_state;
Notify (Ev_state);
}


We will unwittingly consider who called the Void Chg_state (Uint8 cur_state)
The code for the above function is called as shown in red
void Sys_init (void)
{


/* Initialize state machine parameters */
Memset_my (&plc_state, 0x00, sizeof (plc_state));
Memset_my (&reg, 0x00, sizeof (REG));
Reg.type = password_reg;//Power-on password registration
Chg_state (RST_PLC);//This is a reset operation
Chg_state (_end);//noly for debug
Memset_my (G_frame_buffer, 0x00, sizeof (G_frame_buffer));
Ir_eng.g_ir_state = Ir_idle;
}


static void chk_plc_alive (void)
{
if (rst_plc_t > 120)//2 hours without communication, reset the carrier chip
{
rst_plc_t = 0;
Chg_state (RST_PLC);
}
else if (rst_plc_t) | | (+ = rst_plc_t))
{//Read carrier Eid
GET_ID (Cmd_get_eid, G_frame_buffer);
}
}


/**********************************************
Equipment Registration: 1, the first time registration does not use the password;
2, the second time after registration, and the original record of the same gateway number does not use the password
3, the second time after registration, the new network Kwanhla equipment needs to use the device password
***********************************************/
Static uint8 Get_reg (struct shs_frame *pframe)
{
Uint8 need_wr=1;




if (Password_reg = = Reg.type)
{
if (Unvalid_data = = Eep_param.panid_flag)
{//Registration for the first time, do not award paragraph password
}
else if ((Valid_data = = Eep_param.panid_flag)
&& (0x00 = = Memcmp_my (Eep_param.panid, &pframe->infor[1], Panid_len)))
{//After successful registration is completed, start the registration again, only Judge Panid
NEED_WR = 0;
}
else if ((eep_param.pwd_magic = = Valid_data)
&& (0x00! = Memcmp_my (Eep_param.password, &pframe->infor[panid_len+1], Pwd_len)))
{//Determine if the Panid has been registered successfully
Reg.last_status = Password_err;
Chg_state (Pwd_err);
return (0);
}
}
Successful, set password registration successful




Reg.type = Password_reg;
Chg_state (G_GWID);//Read Gateway Aid




if (NEED_WR)
{
mymemcpy (Eep_param.panid, &pframe->infor[1], Panid_len);
Eep_param.panid_flag = Valid_data;
Eep_write (Of_plc_param, (uint8 *) &eep_param, sizeof (Eep_param));
}
return (0);
}
#if 0
{
Uint8 need_wr=1;




if (Password_reg = = Reg.type)
{
if (Invalid_data = = Eep_param.panid_flag)
{//Registration for the first time, do not award paragraph password
}
else if ((Valid_data = = Eep_param.panid_flag)
&& (0x00 = = Memcmp_my (Eep_param.panid, &pframe->infor[1], Panid_len)))
{//After successful registration is completed, start the registration again, only Judge Panid
NEED_WR = 0;
}
else if ((eep_param.pwd_magic = = Valid_data)
&& (0x00! = Memcmp_my (Eep_param.password, &pframe->infor[panid_len+1], Pwd_len)))
{//Determine if the Panid has been registered successfully
Reg.last_status = Password_err;
Chg_state (Pwd_err);
return (0);
}
}
Successful, set password registration successful




Reg.type = Password_reg;
Chg_state (G_GWID);//Read Gateway Aid




if (NEED_WR)
{
mymemcpy (Eep_param.panid, &pframe->infor[1], Panid_len);
Eep_param.panid_flag = Valid_data;
Eep_write (Of_plc_param, (uint8 *) &eep_param, sizeof (Eep_param));
}
return (0);
}
#endif

Static uint8 Get_reg (struct shs_frame *pframe) This function is called by the function, by void local_frame_opt (struct shs_frame *pframe)


/****************************************************************
Local communication Protocol resolution
****************************************************************/
void local_frame_opt (struct shs_frame *pframe)
{
if (cmd_reginfor = = Pframe->infor[0])
{
Get_reg (pframe);
}
else if (Cmd_req_aid = = Pframe->infor[0])
{
Chg_state (S_aid);//carrier active access AID, indicating that the carrier chip may be reset.
}
else if (Cmd_unlink = = Pframe->infor[0])
{//Gateway disconnected, carrier chip escalated disconnect, start carrier registration Panid settings ....
Chg_state (S_pwdreg);
}
else if (Cmd_get_gwaid = = Pframe->infor[0])
//    {
mymemcpy (eep_param.gateway_id, &pframe->infor[1], Id_len);
Eep_write (Of_plc_param, (uint8 *) &eep_param, sizeof (Eep_param));
//    }

}

Our question comes again, the function called void local_frame_opt (struct shs_frame *pframe) The answer is Uint8 frame_handle (uint8 init, void *args) protocol parsing function

Uint8 Frame_handle (uint8 init, void *args)
{
Uint8 Len,ret;
struct Shs_frame *pframe = (struct shs_frame *) args;


if (pframe = = NULL) return (0);
if (Is_all_xx (Pframe->said, 0x00, Id_len))
{//local communication
Local_frame_opt (pframe);
return (1);
}
Else
{//Offsite communication
ret = remote_frame_opt (pframe);
if (Ret > 1) {
Len = Set_ret_frame (pframe, ret);
Uart_write ((uint8 *) pframe, Len);
}
}

return (0);
}

That function called the function uint8 frame_handle (uint8 init, void *args) .... The answer is the following structure

struct plc_state
{
Uint8 cur_state;
Uint8 next_state;


Uint8 (*action) (uint8 init, void *args);//How does this structure work?

};

const struct Plc_state plc_state_slot[]=
{
Init plc
{RST_PLC, R_eid, RESET_PLC},
{R_eid, s_bps, Rd_plc_eid},
{R_eid, S_aid, Rd_plc_eid},
{s_bps, S_aid, wr_plc_bps},
{s_aid, S_pwdreg,wr_plc_aid},
{S_pwdreg, S_panid, Set_register},
{S_panid, _end, Wr_plc_panid},
#if Key_reg
Key Reg
{UNLINK1, S_reg, Set_unlink},
#endif

Password Registration
{pwd_err, UNLINK2, Set_register},
{UNLINK2, S_panid, Set_unlink},
Registration successful
{g_gwid, S_reg, Rd_gw_aid},
{S_reg, G_sid, set_register},//set the registration properties, wait for the carrier chip to escalate Panid
{g_sid, _end, Rd_gw_sid},


{_end, _end, Frame_handle},
};

The following function re-invokes the plc_state_slot[]

/****************************************
Carrier initialization State transitions
****************************************/
void Chg_state (Uint8 cur_state)
{
Uint8 i;
Static Uint8 Last_state=invalid;

plc_state.wait_t = 0;
Plc_state.init=1;
for (i = 0; i < PLC_SLOT_SZ; i++)
{
if (plc_state_slot[i].cur_state = = cur_state)
{
Plc_state.pstate = (struct plc_state *) &plc_state_slot[i];
Break
}
}
if (i >= PLC_SLOT_SZ)
{
Plc_state.pstate = (struct plc_state *) &plc_state_slot[0];
}


if (last_state! = plc_state.pstate->cur_state)
{
plc_state.trycnt = 0;
}
Last_state = plc_state.pstate->cur_state;
Notify (Ev_state);
}


void plc_machine_opt (void *args)
{
struct Plc_state *pstate = plc_state.pstate;
Uint8 Init;


init = Plc_state.init;
if (init) plc_state.wait_t=0;
Plc_state.init = 0;
if (NULL! = pstate)
{
Pstate->action (init, args); Calling this function is equivalent to mobilizing the struct const struct Plc_state plc_state_slot[]= ...
}
}


The analysis of the code to this end, some do not understand the place to go back to the company to ask a master, or let me ask my Master buddies. Analysis Endless, I will insist, code is to break the sand pot ask the end. Find out the real side of the code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.