#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "at_cmd.h"
#include "utils.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "M5310.h"
#include "fifo.h"
extern int8_t dl_buf_id;
static char cmd_buff[1024];


void hex_to_hexstring(char *src,char *dst,int len)
{
    int i = 0,j = 0;
    for(i=0,j=0;j<len*2;i++,j++)
    {
      if((src[i]<=9)&&(src[i]>=0))
	    {
				dst[j] =  '0';
		    dst[++j] = src[i] + '0';	
      }
      else  if(src[i]>=0x0A&&src[i]<=0x0F)
      {
        dst[j] =  '0';
		    dst[++j] = src[i] + 55;	
      }
      else if (src[i]>=0x0F)
      {
				dst[j] =  src[i]/16 +'0';
				switch (dst[j])
				{
                case '0': dst[j] = '0';break;
                case '1': dst[j] = '1';break;
                case '2': dst[j] = '2';break;
                case '3': dst[j] = '3';break;
                case '4': dst[j] = '4';break;
                case '5': dst[j] = '5';break;
                case '6': dst[j] = '6';break;
                case '7': dst[j] = '7';break;
                case '8': dst[j] = '8';break;
                case '9': dst[j] = '9';break;
                case ':': dst[j] = 'A';break;
                case ';': dst[j] = 'B';break;
                case '<': dst[j] = 'C';break;
                case '=': dst[j] = 'D';break;
                case '>': dst[j] = 'E';break;
                case '?': dst[j] = 'F';break;
                default : break;
				}
				dst[++j] =  src[i]%16 +'0';
				switch (dst[j])
				{
                case '0': dst[j] = '0';break;
                case '1': dst[j] = '1';break;
                case '2': dst[j] = '2';break;
                case '3': dst[j] = '3';break;
                case '4': dst[j] = '4';break;
                case '5': dst[j] = '5';break;
                case '6': dst[j] = '6';break;
                case '7': dst[j] = '7';break;
                case '8': dst[j] = '8';break;
                case '9': dst[j] = '9';break;
                case ':': dst[j] = 'A';break;
                case ';': dst[j] = 'B';break;
                case '<': dst[j] = 'C';break;
                case '=': dst[j] = 'D';break;
                case '>': dst[j] = 'E';break;
                case '?': dst[j] = 'F';break;
                default : break;
					}
				}
               
				}	 
		 strcat(dst,",1,1\r\n");
		// nbiot_printf(dst);
		 return;
}


uint32_t ip_SendData(int8_t * buf, uint32_t len)
{
     SendCmd(buf,"OK",100);
     return len;
}

void netif_rx(uint8_t*buf,uint16_t *read)
{
     uint8_t *msg_p=NULL;
     uint8_t ptr[1024]={0};
     *read=fifo_get(dl_buf_id,ptr);
     if(*read!=0)
     {
        if((msg_p= strstr((const char *)ptr, "+MIPL"))!=NULL)
        {              
           memcpy(buf,ptr,*read);
        }else{
        
           *read=0;
        }
     }
       
}
void M5310_Power_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);	 //使能PB,PE端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				 //LED0-->PB.9 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOC, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.5
 GPIO_SetBits(GPIOC,GPIO_Pin_4);						 //PB.5 输出高
 //GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出高 
}

void netdev_init(void)
{
	  
	  SendCmd("AT+NRB\r\n", "OK", 5000); 
	  SendCmd("AT+CIMI\r\n", "OK", 5000);
	  //SendCmd("AT+CGMR\r\n", "OK", 5000);
	  SendCmd("AT+CMEE=1\r\n","OK", 5000);
    SendCmd("AT+CSCON=1\r\n","OK", 5000);  
    SendCmd("AT+CEREG=2\r\n","OK", 5000); 
    SendCmd("AT+CSCON?\r\n","CSCON:1,1", 5000); 
    SendCmd("AT+CEREG?\r\n","CEREG:2,1", 5000); 
	  SendCmd("AT+csq\r\n", "OK", 5000); 
    SendCmd("AT+CGDCONT?\r\n", "OK", 5000);
    printf("connect NBIOT sucess\r\n");
} 


void output_buffer1(unsigned char *buffer, int length,int index, int flag)
{
	int i = 0;
	while ( i < length )
	{
		printf( "%02X", buffer[i++] );
	}
	printf(",%d,%d\r\n",index,flag);
}
/*****************************************************************
       0               1               2               3 
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| boot | encrypt|     debug     |          local_port         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          life_time                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           host_len            |             host            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          ep_name_len          |      ep_name(imei;imsi)     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  coap_block1  |  coap_block2  |    block2th   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*****************************************************************/
void mipl_generate(char *buf, size_t buflen, MIPL_T *mipl)
{
	//strcpy(buf,"AT+MIPLCONF=46,000000002C0100001900636F61703A2F2F3138332E3233302E34302E34303A353638330900313233343B6675636B,1,1\r\n");
//	SendCmd(buf,"OK",300);
	uint32_t offset = 0;
	int mipl_num = 0;
	char mode,temp[5];
	memset(buf, 0, buflen);

	mode = ((mipl->boot & 0x1) << 4) | (mipl->encrypt & 0x1);
	memcpy(buf + offset, &mode, 1);
	offset++;
	memcpy(buf + offset, &mipl->debug, 1);
	offset++;
	memcpy(buf + offset, &mipl->port, 2);
	offset += 2;
	memcpy(buf+offset, &mipl->keep_alive, 4);
	offset += 4;

	memcpy(buf + offset, &mipl->uri_len, 2);
	offset += 2;
	memcpy(buf + offset, mipl->uri, mipl->uri_len);
	offset += mipl->uri_len;
	memcpy(buf + offset, &mipl->ep_len, 2);
	offset += 2;
	memcpy(buf + offset, mipl->ep, mipl->ep_len);
	offset += mipl->ep_len;

	mipl_num = 0;
	while(offset > 512)//??+MIPLCONF??????1024??????
	{
		printf("MIPLCONF is too long\r\n");
		return ;
	}
	
	strcpy(cmd_buff,"AT+MIPLCONF=");
  nbiot_itoa(offset,temp,5);
	strcat(cmd_buff,temp);
	strcat(cmd_buff,",");
	hex_to_hexstring(buf,cmd_buff+strlen(cmd_buff),offset);
	SendCmd(cmd_buff,"OK",300);
	//output_buffer1( (unsigned char *)(buf + (mipl_num >> 10)),offset,mipl_num + 1,1);//??
}

void init_miplconf(u32 lifetime,const char *uri,const char *ep)
{
	  MIPL_T mipl;
	  char buffer[512];
	  mipl.boot=MIPL_BOOT;
	  mipl.encrypt=MIPL_ENCRYPT;
		mipl.debug=MIPL_DEBUG;
		mipl.port=MIPL_PORT;
		mipl.keep_alive=lifetime;
		mipl.uri=uri;
		mipl.uri_len=strlen(uri);
		mipl.ep=ep;
		mipl.ep_len=strlen(ep);
    mipl_generate(buffer,sizeof(buffer),&mipl);
}


void m5310_addobj(uint16_t		objid,
  	              uint16_t		instid)
{
	char tmp[10];
	memset(cmd_buff,0,50);
	memcpy(cmd_buff,"AT+MIPLADDOBJ=0,",strlen("AT+MIPLADDOBJ=0,"));
	nbiot_itoa(objid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	nbiot_itoa(instid,tmp,1);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,"\r\n");
	SendCmd(cmd_buff,"OK",300);
}

void m5310_delobj(uint16_t  objid,
				       uint16_t  instid)
{
	 char tmp[10];
	 memset(cmd_buff,0,50);
	 memcpy(cmd_buff,"AT+MIPLDELOBJ=0,",strlen("AT+MIPLDELOBJ=0,"));
	 nbiot_itoa(objid,tmp,10);
	 strcat(cmd_buff,tmp);
	 strcat(cmd_buff,",");
	 nbiot_itoa(instid,tmp,10);
	 strcat(cmd_buff,tmp);
	 strcat(cmd_buff,"\r\n");
	 SendCmd(cmd_buff,"OK",300);
 }


 size_t m5310_register_request( uint8_t  *buffer,									    
                                size_t    buffer_len)
{   
    size_t  len=0;
	len=strlen("AT+MIPLOPEN=0,15\r\n")+1;
	if(len<buffer_len){
	 memcpy(buffer,"AT+MIPLOPEN=0,15\r\n",len);
	 SendCmd("AT+MIPLOPEN=0,15\r\n","OK",300);
	 return len;
   }
	return 0;
}

 size_t m5310_close_request( uint8_t  *buffer,									    
                             size_t    buffer_len)
{   
    size_t  len=0;
	len=strlen("AT+MIPLCLOSE=0\r\n")+1;
	if(len<buffer_len){
	 memcpy(buffer,"AT+MIPLCLOSE=0\r\n",len);
	 SendCmd("AT+MIPLCLOSE=0\r\n","OK",300);
	 return len;
   }
	return 0;
}  


 void m5310_notify_upload(const nbiot_uri_t *uri,uint8_t type,char *data,int tranmmit,uint16_t ackid)
{
	
  char tmp[10];
	memset(cmd_buff,0,sizeof(cmd_buff));
	memcpy(cmd_buff,"AT+MIPLNOTIFY=0,",strlen("AT+MIPLNOTIFY=0,"));
	nbiot_itoa(uri->objid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	nbiot_itoa(uri->instid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	nbiot_itoa(uri->resid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
  nbiot_itoa(type,tmp,1);
  strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	strcat(cmd_buff,"\"");
	strcat(cmd_buff,data);
	strcat(cmd_buff,"\"");
	strcat(cmd_buff,",");
  nbiot_itoa(tranmmit,tmp,1);
	strcat(cmd_buff,tmp);
#ifdef NOTIFY_ACK
if(tranmmit==1){
	strcat(cmd_buff,",");
	nbiot_itoa(ackid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,"\r\n");
}else{

   strcat(cmd_buff,"\r\n");

}	
	
#else

    strcat(cmd_buff,"\r\n");

#endif
	  SendCmd(cmd_buff,"OK",300);
}

 void m5310_read_upload(const nbiot_uri_t *uri,uint8_t type,char *data,int tranmmit,uint16_t ackid)
{
	
    char tmp[10];
	memset(cmd_buff,0,sizeof(cmd_buff));
	memcpy(cmd_buff,"AT+MIPLREAD=0,",strlen("AT+MIPLREAD=0,"));
	nbiot_itoa(ackid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	nbiot_itoa(uri->objid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	nbiot_itoa(uri->instid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	nbiot_itoa(uri->resid,tmp,10);
	strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
  nbiot_itoa(type,tmp,1);
  strcat(cmd_buff,tmp);
	strcat(cmd_buff,",");
	strcat(cmd_buff,"\"");
	strcat(cmd_buff,data);
	strcat(cmd_buff,"\"");
	strcat(cmd_buff,",");
  nbiot_itoa(tranmmit,tmp,1);
	strcat(cmd_buff,tmp);
  strcat(cmd_buff,"\r\n");
	SendCmd(cmd_buff,"OK",300);
}

void m5310_write_rsp(int suc,uint16_t ackid)
{
   char tmp[10];
	 memset(cmd_buff,0,50);
   memcpy(cmd_buff,"AT+MIPLWRITE=0,",strlen("AT+MIPLWRITE=0,"));
	 nbiot_itoa(ackid,tmp,10);
	 strcat(cmd_buff,tmp);
	 strcat(cmd_buff,",");
	 nbiot_itoa(suc,tmp,1);
	 strcat(cmd_buff,tmp);
	 strcat(cmd_buff,"\r\n");
	 SendCmd(cmd_buff,"OK",300);
  
}

void m5310_execute_rsp(int suc,uint16_t ackid)
{
     char tmp[10];
	 memset(cmd_buff,0,50);
	 memcpy(cmd_buff,"AT+MIPLEXECUTE=0,",strlen("AT+MIPLEXECUTE=0,"));
	 nbiot_itoa(ackid,tmp,10);
	 strcat(cmd_buff,tmp);
	 strcat(cmd_buff,",");
	 nbiot_itoa(suc,tmp,1);
	 strcat(cmd_buff,tmp);
	 strcat(cmd_buff,"\r\n");
   SendCmd(cmd_buff,"OK",300);
  
}

 
