主题:求助用delphi实现蓝牙L2CAP协议中的拆包和重组过程
课题是要求用Delphi实现蓝牙L2CAP协议中的拆包和重组功能,本人是个新手,对Delphi语言不太熟悉,特求专家解答。具体如下:
[b]library[/b] Adaptor;
[b]uses[/b]
Windows,
SysUtils,
Classes;
{总体说明:
1。DLL文件可以看成就是将函数封装成函数包,不同的开发人员独立开发各自的函数包,
开发好的函数包可以在开发人员之间共享;
2。本DLL文件封装了两个函数,即数据包的切割函数和包的组合函数。
设计思想:
数据包的实际上就是内存中的一段数据,您的任务就是将一串比较长的数据分割开
发送出去,在接受端再将它组合成原来的数据。
拆分方法:长度不定上层的数据包成250Bytes长的子包发出,本实验采用1+249Bytes
的子包格式,即第1个字节为标志域表明子包是否为拆分后的最后一个子包($00表明不是
,$80表明是),后249个字节是信息数据包的内容。
接收办法:接收到子包,就放入缓存,缓存指针后移,缓存大小也增加;同时判断第
一个字节是否为$80,如果是函数返回值为True(表明应用程序可以从缓存中取走包),不
是返回值为False。
常用Delphi命令:
GetMem(指针,内存大小) 给某指针分配一段内存
FreeMem(指针) 收回指针指向的内存
指针=ptr(Integer(指针)+n字节) 将指针向后移n字节
Move(指针1^,指针2^,n字节); 将指针1指向的地址开始的n个字节复制到指针2指向的地址
举例,
将包指针志向的第一个字节赋值成$00
PByte 指向单字节的指针
P 包指针
命令行
PByte^:=$00;
move(PByte^, P^, 1);
}
{以下为DLL_LLCSendData函数
这从另一个DLL函数中导入的函数,为DLL函数内部使用的函数,不需要导出
功能:将数据包发送到数据链路层
说明:无须编程}
[b]function[/b] DLL_LLCSendData (LLCHandle:Word; length:Word; pData:Pointer; IsLast:Byte): Byte; [b]cdecl[/b]; [b]external[/b] 'HCI_DLL.dll';
{以下为SPlitPk过程
功能:分割包,并将它发送到数据链路层
说明:基本框架留出,请按说明填入部分程序
函数引用到的参数:
Pk_Pointer:Pointer; 上层传下的包指针
Pk_Length:Cardinal; 上层传下的包长度
Output_Length:Cardinal; 数据链路层的包长度,本实验在调用函数时已赋值为250
LLC_Handle:Byte; 逻辑链路标号
}
[b]procedure[/b] SplitPk(Pk_Pointer:Pointer; Pk_Length:Cardinal; Output_Length:Cardinal; LLC_Handle:Byte);
[b]var[/b]
Output_Pk:Pointer; //指向待处理包包头的指针
Temp_Pointer:Pointer; //临时指针
PInfo:Pointer; //指向子包信息域的指针
Remain_Length:Cardinal; //未处理的长度
PByte:^Byte; //指向单字节的指针
Info_Length:Cardinal; //信息域的长度
[b]begin[/b]
GetMem(Output_Pk, Output_Length); //给传出包指针分配一段内存
New(PByte); //给单字节指针分配一段内存
PInfo:=ptr(Integer(Output_Pk)+1); //信息域指针指向信息域
Temp_Pointer:=ptr(Integer(Pk_Pointer)); //临时指针指向待处理包的包头
Remain_Length:=Pk_Length; //初始化剩余包长
[b]While[/b] Remain_Length>0 [b]do[/b] [b]begin[/b]
[b]if[/b] Remain_Length>(Output_Length-1) [b]then[/b] //如果待处理包剩余的长度大于子包信息域最大长度
[b]begin[/b]
PByte^:=$00; //将单字节指针指向的值赋值为$00
move(PByte^, Output_Pk^, 1); //将$00复制到子包的标志域
Info_Length:= Output_Length-1; //定义子包信息域的长度
move(Temp_Pointer^, PInfo^, Info_Length); //将上层包的一部分复制到子包的信息域
Temp_Pointer:=ptr(Integer(Temp_Pointer)+Output_Length-1); //将指向待处理包的临时指针向后移,移过已处理的部分
DLL_LLCSendData(LLC_Handle, Output_Length, Output_Pk, 0); //调用发送函数蒋子包发出
Remain_Length:=Remain_Length-Output_Length+1; //改变待处理包剩余的长度
[b]end[/b]
[b]else[/b]
[b]begin [/b] //如果待处理包剩余长度小于子包信息域最大长度,意味着最后一个子包
//****************************************************************//
[align=center][b]所求程序[/b][/align]
//***************************************************************//
DLL_LLCSendData(LLC_Handle, Info_Length+1, Output_Pk, 1); //调用发送函数蒋子包发出
[b]end[/b];
[b]end[/b];
FreeMem(Output_Pk);
FreeMem(PByte);
[b]end[/b];
{以下为AssemblePk过程
功能:组合包,并将它发送到会话层
说明:定义好需要的变量指针,请按说明填入部分程序,本函数由数据链路层调用,传入
的包指针就是数据链路层的包
函数引用到的参数:
Pk_Pointer:Pointer; 下层传上的包指针
Pk_Length:Cardinal; 下层传来包的长度
Buf_Temp:Cardinal; 组包缓存的指针,是全局变量,
将下层包的信息域复制到该指针指向的地址,然后将该指针向后移信息域的长度
Buf_Length:Cardinal; 缓存的长度,是全局变量,
每移入一个下层包的信息域,就将该长度加上信息域的长度
返回值:
Boolean型,如果下层传来的是最后一个包,返回True,反之返回False
}
[b]function[/b] AssemblePk(Pk_Pointer:Pointer; Pk_Length:Cardinal; [b]var[/b] Buf_Temp:Pointer; [b]var [/b]Buf_Length:Cardinal):Boolean;
[b]var[/b]
PByte:^Byte;
Temp_Pointer:Pointer;
[b]begin[/b]
New(PByte);
//**************************************************************//
[align=center][b]所求程序[/b][/align]
//***************************************************************//
FreeMem(PByte);
[b]end[/b];
{以下为函数导出的接口定义}
exports
SplitPk Index 0,
AssemblePk Index 1;
[b]end[/b].
[b]library[/b] Adaptor;
[b]uses[/b]
Windows,
SysUtils,
Classes;
{总体说明:
1。DLL文件可以看成就是将函数封装成函数包,不同的开发人员独立开发各自的函数包,
开发好的函数包可以在开发人员之间共享;
2。本DLL文件封装了两个函数,即数据包的切割函数和包的组合函数。
设计思想:
数据包的实际上就是内存中的一段数据,您的任务就是将一串比较长的数据分割开
发送出去,在接受端再将它组合成原来的数据。
拆分方法:长度不定上层的数据包成250Bytes长的子包发出,本实验采用1+249Bytes
的子包格式,即第1个字节为标志域表明子包是否为拆分后的最后一个子包($00表明不是
,$80表明是),后249个字节是信息数据包的内容。
接收办法:接收到子包,就放入缓存,缓存指针后移,缓存大小也增加;同时判断第
一个字节是否为$80,如果是函数返回值为True(表明应用程序可以从缓存中取走包),不
是返回值为False。
常用Delphi命令:
GetMem(指针,内存大小) 给某指针分配一段内存
FreeMem(指针) 收回指针指向的内存
指针=ptr(Integer(指针)+n字节) 将指针向后移n字节
Move(指针1^,指针2^,n字节); 将指针1指向的地址开始的n个字节复制到指针2指向的地址
举例,
将包指针志向的第一个字节赋值成$00
PByte 指向单字节的指针
P 包指针
命令行
PByte^:=$00;
move(PByte^, P^, 1);
}
{以下为DLL_LLCSendData函数
这从另一个DLL函数中导入的函数,为DLL函数内部使用的函数,不需要导出
功能:将数据包发送到数据链路层
说明:无须编程}
[b]function[/b] DLL_LLCSendData (LLCHandle:Word; length:Word; pData:Pointer; IsLast:Byte): Byte; [b]cdecl[/b]; [b]external[/b] 'HCI_DLL.dll';
{以下为SPlitPk过程
功能:分割包,并将它发送到数据链路层
说明:基本框架留出,请按说明填入部分程序
函数引用到的参数:
Pk_Pointer:Pointer; 上层传下的包指针
Pk_Length:Cardinal; 上层传下的包长度
Output_Length:Cardinal; 数据链路层的包长度,本实验在调用函数时已赋值为250
LLC_Handle:Byte; 逻辑链路标号
}
[b]procedure[/b] SplitPk(Pk_Pointer:Pointer; Pk_Length:Cardinal; Output_Length:Cardinal; LLC_Handle:Byte);
[b]var[/b]
Output_Pk:Pointer; //指向待处理包包头的指针
Temp_Pointer:Pointer; //临时指针
PInfo:Pointer; //指向子包信息域的指针
Remain_Length:Cardinal; //未处理的长度
PByte:^Byte; //指向单字节的指针
Info_Length:Cardinal; //信息域的长度
[b]begin[/b]
GetMem(Output_Pk, Output_Length); //给传出包指针分配一段内存
New(PByte); //给单字节指针分配一段内存
PInfo:=ptr(Integer(Output_Pk)+1); //信息域指针指向信息域
Temp_Pointer:=ptr(Integer(Pk_Pointer)); //临时指针指向待处理包的包头
Remain_Length:=Pk_Length; //初始化剩余包长
[b]While[/b] Remain_Length>0 [b]do[/b] [b]begin[/b]
[b]if[/b] Remain_Length>(Output_Length-1) [b]then[/b] //如果待处理包剩余的长度大于子包信息域最大长度
[b]begin[/b]
PByte^:=$00; //将单字节指针指向的值赋值为$00
move(PByte^, Output_Pk^, 1); //将$00复制到子包的标志域
Info_Length:= Output_Length-1; //定义子包信息域的长度
move(Temp_Pointer^, PInfo^, Info_Length); //将上层包的一部分复制到子包的信息域
Temp_Pointer:=ptr(Integer(Temp_Pointer)+Output_Length-1); //将指向待处理包的临时指针向后移,移过已处理的部分
DLL_LLCSendData(LLC_Handle, Output_Length, Output_Pk, 0); //调用发送函数蒋子包发出
Remain_Length:=Remain_Length-Output_Length+1; //改变待处理包剩余的长度
[b]end[/b]
[b]else[/b]
[b]begin [/b] //如果待处理包剩余长度小于子包信息域最大长度,意味着最后一个子包
//****************************************************************//
[align=center][b]所求程序[/b][/align]
//***************************************************************//
DLL_LLCSendData(LLC_Handle, Info_Length+1, Output_Pk, 1); //调用发送函数蒋子包发出
[b]end[/b];
[b]end[/b];
FreeMem(Output_Pk);
FreeMem(PByte);
[b]end[/b];
{以下为AssemblePk过程
功能:组合包,并将它发送到会话层
说明:定义好需要的变量指针,请按说明填入部分程序,本函数由数据链路层调用,传入
的包指针就是数据链路层的包
函数引用到的参数:
Pk_Pointer:Pointer; 下层传上的包指针
Pk_Length:Cardinal; 下层传来包的长度
Buf_Temp:Cardinal; 组包缓存的指针,是全局变量,
将下层包的信息域复制到该指针指向的地址,然后将该指针向后移信息域的长度
Buf_Length:Cardinal; 缓存的长度,是全局变量,
每移入一个下层包的信息域,就将该长度加上信息域的长度
返回值:
Boolean型,如果下层传来的是最后一个包,返回True,反之返回False
}
[b]function[/b] AssemblePk(Pk_Pointer:Pointer; Pk_Length:Cardinal; [b]var[/b] Buf_Temp:Pointer; [b]var [/b]Buf_Length:Cardinal):Boolean;
[b]var[/b]
PByte:^Byte;
Temp_Pointer:Pointer;
[b]begin[/b]
New(PByte);
//**************************************************************//
[align=center][b]所求程序[/b][/align]
//***************************************************************//
FreeMem(PByte);
[b]end[/b];
{以下为函数导出的接口定义}
exports
SplitPk Index 0,
AssemblePk Index 1;
[b]end[/b].